diff options
author | Piotr Dziwinski <piotrdz@gmail.com> | 2012-06-26 22:23:05 +0200 |
---|---|---|
committer | Piotr Dziwinski <piotrdz@gmail.com> | 2012-06-26 22:23:05 +0200 |
commit | ebed57aa22b772211387a5561f995eee8f5faed1 (patch) | |
tree | 9a0b08371df54c125957e63c7ecff81c001d4eaf /src/object/auto | |
parent | fc5389d18816799ba2698914384cd099ba8a7a6c (diff) | |
download | colobot-ebed57aa22b772211387a5561f995eee8f5faed1.tar.gz colobot-ebed57aa22b772211387a5561f995eee8f5faed1.tar.bz2 colobot-ebed57aa22b772211387a5561f995eee8f5faed1.zip |
Whitespace and language change
- changed tabs to spaces and DOS line endings to Unix
(except in CBot and metafile)
- changed language to English
- fixed #include <d3d.h> in d3dengine.h
Diffstat (limited to 'src/object/auto')
52 files changed, 13757 insertions, 13757 deletions
diff --git a/src/object/auto/auto.cpp b/src/object/auto/auto.cpp index 9635265..f2764e2 100644 --- a/src/object/auto/auto.cpp +++ b/src/object/auto/auto.cpp @@ -1,437 +1,437 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/auto.h"
-
-
-#include "common/iman.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/gauge.h"
-#include "ui/window.h"
-
-
-
-
-// Object's constructor.
-
-CAuto::CAuto(CInstanceManager* iMan, CObject* object)
-{
- m_iMan = iMan;
- m_iMan->AddInstance(CLASS_AUTO, this, 100);
-
- m_object = object;
- m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT);
- m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
- m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE);
- m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT);
- m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN);
- m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER);
- m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD);
- m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET);
- m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ);
- m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA);
- m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE);
- m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
- m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT);
- m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND);
-
- m_type = m_object->RetType();
- m_time = 0.0f;
- m_lastUpdateTime = 0.0f;
- m_bMotor = false;
- m_progressTime = 0.0f;
- m_progressTotal = 1.0f;
-
- Init();
-}
-
-// Object's destructor.
-
-CAuto::~CAuto()
-{
- m_iMan->DeleteInstance(CLASS_AUTO, this);
-}
-
-
-// Destroys the object.
-
-void CAuto::DeleteObject(bool bAll)
-{
-}
-
-
-// Initialize the object.
-
-void CAuto::Init()
-{
- m_bBusy = false;
-}
-
-// Starts the object.
-
-void CAuto::Start(int param)
-{
-}
-
-
-// Give a type.
-
-bool CAuto::SetType(ObjectType type)
-{
- return false;
-}
-
-// Gives a value.
-
-bool CAuto::SetValue(int rank, float value)
-{
- return false;
-}
-
-// Gives the string.
-
-bool CAuto::SetString(char *string)
-{
- return false;
-}
-
-
-// Management of an event.
-
-bool CAuto::EventProcess(const Event &event)
-{
- if ( event.event == EVENT_FRAME &&
- !m_engine->RetPause() )
- {
- m_time += event.rTime;
- UpdateInterface(event.rTime);
- }
-
- if ( !m_object->RetSelect() ) // robot not selected?
- {
- return true;
- }
-
- return true;
-}
-
-// Indicates whether the controller has finished its activity.
-
-Error CAuto::IsEnded()
-{
- return ERR_CONTINUE;
-}
-
-// Stops the controller
-
-bool CAuto::Abort()
-{
- return false;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAuto::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, dim, ddim;
- float ox, oy, sx, sy;
- char name[100];
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw != 0 )
- {
- pw->Flush(); // destroys the window buttons
- m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window
- }
-
- if ( !bSelect ) return true;
-
- pos.x = 0.0f;
- pos.y = 0.0f;
- dim.x = 540.0f/640.0f;
-//? dim.y = 70.0f/480.0f;
- dim.y = 86.0f/480.0f;
- m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0);
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- m_object->GetTooltipName(name);
- pos.x = 0.0f;
- pos.y = 64.0f/480.0f;
- ddim.x = 540.0f/640.0f;
- ddim.y = 16.0f/480.0f;
- pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, name);
-
- dim.x = 33.0f/640.0f;
- dim.y = 33.0f/480.0f;
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*7.0f;
- pos.y = oy+sy*0.6f;
- ddim.x = 160.0f/640.0f;
- ddim.y = 26.0f/480.0f;
- pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GPROGRESS);
-
- if ( m_type != OBJECT_BASE &&
- m_type != OBJECT_SAFE &&
- m_type != OBJECT_HUSTON )
- {
- pos.x = ox+sx*2.1f;
- pos.y = oy+sy*0;
- ddim.x = dim.x*0.6f;
- ddim.y = dim.y*0.6f;
- pw->CreateButton(pos, ddim, 12, EVENT_OBJECT_DELETE);
- }
-
-#if 0
- pos.x = ox+sx*12.4f;
- pos.y = oy+sy*1;
- pw->CreateButton(pos, dim, 63, EVENT_OBJECT_BHELP);
-
- pos.x = ox+sx*12.4f;
- pos.y = oy+sy*0;
- pw->CreateButton(pos, dim, 19, EVENT_OBJECT_HELP);
-
- if ( m_main->RetSceneSoluce() )
- {
- pos.x = ox+sx*13.4f;
- pos.y = oy+sy*1;
- pw->CreateButton(pos, dim, 20, EVENT_OBJECT_SOLUCE);
- }
-
- pos.x = ox+sx*13.4f;
- pos.y = oy+sy*0;
- pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT);
-#else
- pos.x = ox+sx*12.3f;
- pos.y = oy+sy*-0.1f;
- ddim.x = dim.x*1.0f;
- ddim.y = dim.y*2.1f;
- pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue background
-
- pos.x = ox+sx*12.3f;
- pos.y = oy+sy*1;
- pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom
-
- pos.x = ox+sx*12.4f;
- pos.y = oy+sy*0.5f;
- ddim.x = dim.x*0.8f;
- ddim.y = dim.y*0.5f;
- pw->CreateButton(pos, ddim, 18, EVENT_OBJECT_BHELP);
- pos.y = oy+sy*0.0f;
- pw->CreateButton(pos, ddim, 19, EVENT_OBJECT_HELP);
-
- pos.x = ox+sx*13.4f;
- pos.y = oy+sy*0;
- pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT);
-#endif
-
- pos.x = ox+sx*14.9f;
- pos.y = oy+sy*0;
- ddim.x = 14.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD);
-
- UpdateInterface();
- m_lastUpdateTime = 0.0f;
- UpdateInterface(0.0f);
-
- return true;
-}
-
-// Change the state of a button interface.
-
-void CAuto::CheckInterface(CWindow *pw, EventMsg event, bool bState)
-{
- CControl* control;
-
- control = pw->SearchControl(event);
- if ( control == 0 ) return;
-
- control->SetState(STATE_CHECK, bState);
-}
-
-// Change the state of a button interface.
-
-void CAuto::EnableInterface(CWindow *pw, EventMsg event, bool bState)
-{
- CControl* control;
-
- control = pw->SearchControl(event);
- if ( control == 0 ) return;
-
- control->SetState(STATE_ENABLE, bState);
-}
-
-// Change the state of a button interface.
-
-void CAuto::VisibleInterface(CWindow *pw, EventMsg event, bool bState)
-{
- CControl* control;
-
- control = pw->SearchControl(event);
- if ( control == 0 ) return;
-
- control->SetState(STATE_VISIBLE, bState);
-}
-
-// Change the state of a button interface.
-
-void CAuto::DeadInterface(CWindow *pw, EventMsg event, bool bState)
-{
- CControl* control;
-
- control = pw->SearchControl(event);
- if ( control == 0 ) return;
-
- control->SetState(STATE_DEAD, !bState);
-}
-
-// Change the state of a button interface.
-
-void CAuto::UpdateInterface()
-{
- CWindow* pw;
-
- if ( !m_object->RetSelect() ) return;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- VisibleInterface(pw, EVENT_OBJECT_GPROGRESS, m_bBusy);
-}
-
-// Updates the state of all buttons on the interface,
-// following the time that elapses ...
-
-void CAuto::UpdateInterface(float rTime)
-{
- CWindow* pw;
- CGauge* pg;
-
- if ( m_time < m_lastUpdateTime+0.1f ) return;
- m_lastUpdateTime = m_time;
-
- if ( !m_object->RetSelect() ) return;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GSHIELD);
- if ( pg != 0 )
- {
- pg->SetLevel(m_object->RetShield());
- }
-
- pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GPROGRESS);
- if ( pg != 0 )
- {
- pg->SetLevel(m_progressTime);
- }
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAuto::RetError()
-{
- return ERR_OK;
-}
-
-
-// Management of the occupation.
-
-bool CAuto::RetBusy()
-{
- return m_bBusy;
-}
-
-void CAuto::SetBusy(bool bBusy)
-{
- m_bBusy = bBusy;
-}
-
-void CAuto::InitProgressTotal(float total)
-{
- m_progressTime = 0.0f;
- m_progressTotal = total;
-}
-
-void CAuto::EventProgress(float rTime)
-{
- m_progressTime += rTime/m_progressTotal;
-}
-
-
-// Engine management.
-
-bool CAuto::RetMotor()
-{
- return m_bMotor;
-}
-
-void CAuto::SetMotor(bool bMotor)
-{
- m_bMotor = bMotor;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAuto::Write(char *line)
-{
- char name[100];
-
- sprintf(name, " aType=%d", m_type);
- strcat(line, name);
-
- sprintf(name, " aBusy=%d", m_bBusy);
- strcat(line, name);
-
- sprintf(name, " aTime=%.2f", m_time);
- strcat(line, name);
-
- sprintf(name, " aProgressTime=%.2f", m_progressTime);
- strcat(line, name);
-
- sprintf(name, " aProgressTotal=%.2f", m_progressTotal);
- strcat(line, name);
-
- return false;
-}
-
-// Return all settings to the controller.
-
-bool CAuto::Read(char *line)
-{
- m_type = (ObjectType)OpInt(line, "aType", OBJECT_NULL);
- m_bBusy = OpInt(line, "aBusy", 0);
- m_time = OpFloat(line, "aTime", 0.0f);
- m_progressTime = OpFloat(line, "aProgressTime", 0.0f);
- m_progressTotal = OpFloat(line, "aProgressTotal", 0.0f);
-
- return 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/. + + +#include <stdio.h> + +#include "object/auto/auto.h" + + +#include "common/iman.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/gauge.h" +#include "ui/window.h" + + + + +// Object's constructor. + +CAuto::CAuto(CInstanceManager* iMan, CObject* object) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_AUTO, this, 100); + + m_object = object; + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); + m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET); + m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_type = m_object->RetType(); + m_time = 0.0f; + m_lastUpdateTime = 0.0f; + m_bMotor = false; + m_progressTime = 0.0f; + m_progressTotal = 1.0f; + + Init(); +} + +// Object's destructor. + +CAuto::~CAuto() +{ + m_iMan->DeleteInstance(CLASS_AUTO, this); +} + + +// Destroys the object. + +void CAuto::DeleteObject(bool bAll) +{ +} + + +// Initialize the object. + +void CAuto::Init() +{ + m_bBusy = false; +} + +// Starts the object. + +void CAuto::Start(int param) +{ +} + + +// Give a type. + +bool CAuto::SetType(ObjectType type) +{ + return false; +} + +// Gives a value. + +bool CAuto::SetValue(int rank, float value) +{ + return false; +} + +// Gives the string. + +bool CAuto::SetString(char *string) +{ + return false; +} + + +// Management of an event. + +bool CAuto::EventProcess(const Event &event) +{ + if ( event.event == EVENT_FRAME && + !m_engine->RetPause() ) + { + m_time += event.rTime; + UpdateInterface(event.rTime); + } + + if ( !m_object->RetSelect() ) // robot not selected? + { + return true; + } + + return true; +} + +// Indicates whether the controller has finished its activity. + +Error CAuto::IsEnded() +{ + return ERR_CONTINUE; +} + +// Stops the controller + +bool CAuto::Abort() +{ + return false; +} + + +// Creates all the interface when the object is selected. + +bool CAuto::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, dim, ddim; + float ox, oy, sx, sy; + char name[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw != 0 ) + { + pw->Flush(); // destroys the window buttons + m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window + } + + if ( !bSelect ) return true; + + pos.x = 0.0f; + pos.y = 0.0f; + dim.x = 540.0f/640.0f; +//? dim.y = 70.0f/480.0f; + dim.y = 86.0f/480.0f; + m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0); + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + m_object->GetTooltipName(name); + pos.x = 0.0f; + pos.y = 64.0f/480.0f; + ddim.x = 540.0f/640.0f; + ddim.y = 16.0f/480.0f; + pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, name); + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.6f; + ddim.x = 160.0f/640.0f; + ddim.y = 26.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GPROGRESS); + + if ( m_type != OBJECT_BASE && + m_type != OBJECT_SAFE && + m_type != OBJECT_HUSTON ) + { + pos.x = ox+sx*2.1f; + pos.y = oy+sy*0; + ddim.x = dim.x*0.6f; + ddim.y = dim.y*0.6f; + pw->CreateButton(pos, ddim, 12, EVENT_OBJECT_DELETE); + } + +#if 0 + pos.x = ox+sx*12.4f; + pos.y = oy+sy*1; + pw->CreateButton(pos, dim, 63, EVENT_OBJECT_BHELP); + + pos.x = ox+sx*12.4f; + pos.y = oy+sy*0; + pw->CreateButton(pos, dim, 19, EVENT_OBJECT_HELP); + + if ( m_main->RetSceneSoluce() ) + { + pos.x = ox+sx*13.4f; + pos.y = oy+sy*1; + pw->CreateButton(pos, dim, 20, EVENT_OBJECT_SOLUCE); + } + + pos.x = ox+sx*13.4f; + pos.y = oy+sy*0; + pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); +#else + pos.x = ox+sx*12.3f; + pos.y = oy+sy*-0.1f; + ddim.x = dim.x*1.0f; + ddim.y = dim.y*2.1f; + pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue background + + pos.x = ox+sx*12.3f; + pos.y = oy+sy*1; + pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom + + pos.x = ox+sx*12.4f; + pos.y = oy+sy*0.5f; + ddim.x = dim.x*0.8f; + ddim.y = dim.y*0.5f; + pw->CreateButton(pos, ddim, 18, EVENT_OBJECT_BHELP); + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, ddim, 19, EVENT_OBJECT_HELP); + + pos.x = ox+sx*13.4f; + pos.y = oy+sy*0; + pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT); +#endif + + pos.x = ox+sx*14.9f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD); + + UpdateInterface(); + m_lastUpdateTime = 0.0f; + UpdateInterface(0.0f); + + return true; +} + +// Change the state of a button interface. + +void CAuto::CheckInterface(CWindow *pw, EventMsg event, bool bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_CHECK, bState); +} + +// Change the state of a button interface. + +void CAuto::EnableInterface(CWindow *pw, EventMsg event, bool bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_ENABLE, bState); +} + +// Change the state of a button interface. + +void CAuto::VisibleInterface(CWindow *pw, EventMsg event, bool bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_VISIBLE, bState); +} + +// Change the state of a button interface. + +void CAuto::DeadInterface(CWindow *pw, EventMsg event, bool bState) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_DEAD, !bState); +} + +// Change the state of a button interface. + +void CAuto::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + VisibleInterface(pw, EVENT_OBJECT_GPROGRESS, m_bBusy); +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAuto::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GSHIELD); + if ( pg != 0 ) + { + pg->SetLevel(m_object->RetShield()); + } + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GPROGRESS); + if ( pg != 0 ) + { + pg->SetLevel(m_progressTime); + } +} + + +// Returns an error due the state of the automation. + +Error CAuto::RetError() +{ + return ERR_OK; +} + + +// Management of the occupation. + +bool CAuto::RetBusy() +{ + return m_bBusy; +} + +void CAuto::SetBusy(bool bBusy) +{ + m_bBusy = bBusy; +} + +void CAuto::InitProgressTotal(float total) +{ + m_progressTime = 0.0f; + m_progressTotal = total; +} + +void CAuto::EventProgress(float rTime) +{ + m_progressTime += rTime/m_progressTotal; +} + + +// Engine management. + +bool CAuto::RetMotor() +{ + return m_bMotor; +} + +void CAuto::SetMotor(bool bMotor) +{ + m_bMotor = bMotor; +} + + +// Saves all parameters of the controller. + +bool CAuto::Write(char *line) +{ + char name[100]; + + sprintf(name, " aType=%d", m_type); + strcat(line, name); + + sprintf(name, " aBusy=%d", m_bBusy); + strcat(line, name); + + sprintf(name, " aTime=%.2f", m_time); + strcat(line, name); + + sprintf(name, " aProgressTime=%.2f", m_progressTime); + strcat(line, name); + + sprintf(name, " aProgressTotal=%.2f", m_progressTotal); + strcat(line, name); + + return false; +} + +// Return all settings to the controller. + +bool CAuto::Read(char *line) +{ + m_type = (ObjectType)OpInt(line, "aType", OBJECT_NULL); + m_bBusy = OpInt(line, "aBusy", 0); + m_time = OpFloat(line, "aTime", 0.0f); + m_progressTime = OpFloat(line, "aProgressTime", 0.0f); + m_progressTotal = OpFloat(line, "aProgressTotal", 0.0f); + + return false; +} + diff --git a/src/object/auto/auto.h b/src/object/auto/auto.h index 3928d28..09efdd9 100644 --- a/src/object/auto/auto.h +++ b/src/object/auto/auto.h @@ -1,111 +1,111 @@ -// * 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/.
-
-// auto.h
-
-#pragma once
-
-
-#include "common/misc.h"
-#include "object/object.h"
-
-
-class CInstanceManager;
-class CD3DEngine;
-class CParticule;
-class CLight;
-class CTerrain;
-class CWater;
-class CCloud;
-class CPlanet;
-class CBlitz;
-class CCamera;
-class CInterface;
-class CRobotMain;
-class CDisplayText;
-class CWindow;
-class CSound;
-
-
-
-
-class CAuto
-{
-public:
- CAuto(CInstanceManager* iMan, CObject* object);
- virtual ~CAuto();
-
- virtual void DeleteObject(bool bAll=false);
-
- virtual void Init();
- virtual void Start(int param);
- virtual bool EventProcess(const Event &event);
- virtual Error IsEnded();
- virtual bool Abort();
-
- virtual bool SetType(ObjectType type);
- virtual bool SetValue(int rank, float value);
- virtual bool SetString(char *string);
-
- virtual bool CreateInterface(bool bSelect);
- virtual Error RetError();
-
- virtual bool RetBusy();
- virtual void SetBusy(bool bBuse);
- virtual void InitProgressTotal(float total);
- virtual void EventProgress(float rTime);
-
- virtual bool RetMotor();
- virtual void SetMotor(bool bMotor);
-
- virtual bool Write(char *line);
- virtual bool Read(char *line);
-
-protected:
- void CheckInterface(CWindow *pw, EventMsg event, bool bState);
- void EnableInterface(CWindow *pw, EventMsg event, bool bState);
- void VisibleInterface(CWindow *pw, EventMsg event, bool bState);
- void DeadInterface(CWindow *pw, EventMsg event, bool bState);
- void UpdateInterface();
- void UpdateInterface(float rTime);
-
-protected:
- CInstanceManager* m_iMan;
- CEvent* m_event;
- CD3DEngine* m_engine;
- CParticule* m_particule;
- CLight* m_light;
- CTerrain* m_terrain;
- CWater* m_water;
- CCloud * m_cloud;
- CPlanet * m_planet;
- CBlitz* m_blitz;
- CCamera* m_camera;
- CInterface* m_interface;
- CRobotMain* m_main;
- CDisplayText* m_displayText;
- CObject* m_object;
- CSound* m_sound;
-
- ObjectType m_type;
- bool m_bBusy;
- bool m_bMotor;
- float m_time;
- float m_lastUpdateTime;
- float m_progressTime;
- float m_progressTotal;
-};
-
+// * 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/. + +// auto.h + +#pragma once + + +#include "common/misc.h" +#include "object/object.h" + + +class CInstanceManager; +class CD3DEngine; +class CParticule; +class CLight; +class CTerrain; +class CWater; +class CCloud; +class CPlanet; +class CBlitz; +class CCamera; +class CInterface; +class CRobotMain; +class CDisplayText; +class CWindow; +class CSound; + + + + +class CAuto +{ +public: + CAuto(CInstanceManager* iMan, CObject* object); + virtual ~CAuto(); + + virtual void DeleteObject(bool bAll=false); + + virtual void Init(); + virtual void Start(int param); + virtual bool EventProcess(const Event &event); + virtual Error IsEnded(); + virtual bool Abort(); + + virtual bool SetType(ObjectType type); + virtual bool SetValue(int rank, float value); + virtual bool SetString(char *string); + + virtual bool CreateInterface(bool bSelect); + virtual Error RetError(); + + virtual bool RetBusy(); + virtual void SetBusy(bool bBuse); + virtual void InitProgressTotal(float total); + virtual void EventProgress(float rTime); + + virtual bool RetMotor(); + virtual void SetMotor(bool bMotor); + + virtual bool Write(char *line); + virtual bool Read(char *line); + +protected: + void CheckInterface(CWindow *pw, EventMsg event, bool bState); + void EnableInterface(CWindow *pw, EventMsg event, bool bState); + void VisibleInterface(CWindow *pw, EventMsg event, bool bState); + void DeadInterface(CWindow *pw, EventMsg event, bool bState); + void UpdateInterface(); + void UpdateInterface(float rTime); + +protected: + CInstanceManager* m_iMan; + CEvent* m_event; + CD3DEngine* m_engine; + CParticule* m_particule; + CLight* m_light; + CTerrain* m_terrain; + CWater* m_water; + CCloud * m_cloud; + CPlanet * m_planet; + CBlitz* m_blitz; + CCamera* m_camera; + CInterface* m_interface; + CRobotMain* m_main; + CDisplayText* m_displayText; + CObject* m_object; + CSound* m_sound; + + ObjectType m_type; + bool m_bBusy; + bool m_bMotor; + float m_time; + float m_lastUpdateTime; + float m_progressTime; + float m_progressTotal; +}; + diff --git a/src/object/auto/autobase.cpp b/src/object/auto/autobase.cpp index a13232f..19382b7 100644 --- a/src/object/auto/autobase.cpp +++ b/src/object/auto/autobase.cpp @@ -1,1441 +1,1441 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autobase.h"
-
-#include "common/iman.h"
-#include "old/terrain.h"
-#include "old/cloud.h"
-#include "old/planet.h"
-#include "old/blitz.h"
-#include "math/geometry.h"
-#include "object/robotmain.h"
-#include "physics/physics.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-const float BASE_LAND_TIME = 7.5f; // hard landing
-const float BASE_TAKO_TIME = 10.0f; // hard landing
-const float BASE_DOOR_TIME = 6.0f; // time opening / closing
-const float BASE_DOOR_TIME2 = 2.0f; // time opening / closing suppl.
-const float BASE_PORTICO_TIME_MOVE = 16.0f; // gate advance time
-const float BASE_PORTICO_TIME_DOWN = 4.0f; // gate length down
-const float BASE_PORTICO_TIME_OPEN = 4.0f; // gate opening duration
-const float BASE_TRANSIT_TIME = 15.0f; // transit duration
-
-
-
-
-// Object's constructor.
-
-CAutoBase::CAutoBase(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- m_fogStart = m_engine->RetFogStart();
- m_deepView = m_engine->RetDeepView();
- Init();
- m_phase = ABP_WAIT;
- m_soundChannel = -1;
-}
-
-// Object's destructor.
-
-CAutoBase::~CAutoBase()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoBase::DeleteObject(bool bAll)
-{
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoBase::Init()
-{
- m_bOpen = false;
- m_time = 0.0f;
- m_lastParticule = 0.0f;
- m_lastMotorParticule = 0.0f;
-
- m_pos = m_object->RetPosition(0);
- m_lastPos = m_pos;
-
- m_phase = ABP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-}
-
-
-// Start the object.
-
-void CAutoBase::Start(int param)
-{
- m_phase = ABP_START;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- m_param = param;
-}
-
-
-// Management of an event.
-
-bool CAutoBase::EventProcess(const Event &event)
-{
- Math::Matrix* mat;
- Event newEvent;
- CObject* pObj;
- Math::Vector pos, speed, vibCir, iPos;
- Math::Point dim, p;
- Error err;
- float angle, dist, time, h, len, vSpeed;
- int i, max;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
-
-begin:
- iPos = m_object->RetPosition(0);
-
- if ( m_phase == ABP_START )
- {
- if ( m_param != PARAM_STOP && // not placed on the ground?
- m_param != PARAM_FIXSCENE )
- {
- FreezeCargo(true); // freeze whole cargo
- }
-
- if ( m_param == PARAM_STOP ) // raises the ground?
- {
- m_phase = ABP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
- m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
- m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f);
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f));
- }
-
- pObj = m_main->RetSelectObject();
- m_main->SelectObject(pObj);
- m_camera->SetObject(pObj);
- if ( pObj == 0 )
- {
- m_camera->SetType(CAMERA_BACK);
- }
- else
- {
- m_camera->SetType(pObj->RetCameraType());
- m_camera->SetDist(pObj->RetCameraDist());
- }
-
- m_main->StartMusic();
- }
-
- if ( m_param == PARAM_FIXSCENE ) // raises the ground?
- {
- m_phase = ABP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
- m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
- m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f);
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f));
- }
- }
-
- if ( m_param == PARAM_LANDING ) // Landing?
- {
- m_phase = ABP_LAND;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_LAND_TIME;
-
- m_main->SetMovieLock(true); // blocks everything until the end of the landing
- m_bMotor = true; // lights the jet engine
-
- m_camera->SetType(CAMERA_SCRIPT);
-
- pos = m_pos;
- pos.x -= 150.0f;
- m_terrain->MoveOnFloor(pos);
- pos.y += 10.0f;
- m_camera->SetScriptEye(pos);
- m_posSound = pos;
-
- pos = m_object->RetPosition(0);
- pos.y += 300.0f+50.0f;
- m_camera->SetScriptLookat(pos);
-
- m_camera->FixCamera();
- m_engine->SetFocus(2.0f);
-
- m_engine->SetFogStart(0.9f);
-
- if ( m_soundChannel == -1 )
- {
- m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.3f, 2.0f, true);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, BASE_LAND_TIME, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 2.0f, SOPER_STOP);
- }
-
- m_main->StartMusic();
- }
-
- if ( m_param == PARAM_PORTICO ) // gate on the porch?
- {
- pos = m_object->RetPosition(0);
- m_finalPos = pos;
- pos.z += BASE_PORTICO_TIME_MOVE*5.0f; // back
- pos.y += 10.0f; // rises (the gate)
- m_object->SetPosition(0, pos);
- MoveCargo(); // all cargo moves
-
- m_phase = ABP_PORTICO_MOVE;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_PORTICO_TIME_MOVE;
-
- m_main->StartMusic();
- }
-
- if ( m_param == PARAM_TRANSIT1 ||
- m_param == PARAM_TRANSIT2 ||
- m_param == PARAM_TRANSIT3 ) // transit in space?
- {
- m_phase = ABP_TRANSIT_MOVE;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_TRANSIT_TIME;
-
- m_object->SetAngleZ(0, -Math::PI/2.0f);
- pos = m_object->RetPosition(0);
- pos.y += 10000.0f; // in space
- m_finalPos = pos;
- m_object->SetPosition(0, pos);
-
- m_main->SetMovieLock(true); // blocks everything until the end of the landing
- m_bMotor = true; // lights the jet engine
-
- m_camera->SetType(CAMERA_SCRIPT);
- pos.x += 1000.0f;
- pos.z -= 60.0f;
- pos.y += 80.0f;
- m_camera->SetScriptEye(pos);
- m_posSound = pos;
- m_camera->FixCamera();
- m_engine->SetFocus(1.0f);
-
- BeginTransit();
-
- mat = m_object->RetWorldMatrix(0);
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 10.0f;
- dim.y = dim.x;
- pos = Math::Vector(42.0f, -2.0f, 17.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[0] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
- pos = Math::Vector(17.0f, -2.0f, 42.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[1] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
- pos = Math::Vector(42.0f, -2.0f, -17.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[2] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
- pos = Math::Vector(17.0f, -2.0f, -42.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[3] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
- pos = Math::Vector(-42.0f, -2.0f, 17.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[4] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
- pos = Math::Vector(-17.0f, -2.0f, 42.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[5] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
- pos = Math::Vector(-42.0f, -2.0f, -17.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[6] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
- pos = Math::Vector(-17.0f, -2.0f, -42.0f);
- pos = Transform(*mat, pos);
- m_partiChannel[7] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
-
- if ( m_soundChannel == -1 )
- {
- m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 1.2f, true);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, BASE_TRANSIT_TIME*0.55f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.8f, BASE_TRANSIT_TIME*0.45f, SOPER_STOP);
- }
- }
- }
-
- if ( event.event == EVENT_UPDINTERFACE )
- {
- if ( m_object->RetSelect() ) CreateInterface(true);
- }
-
- if ( event.event == EVENT_OBJECT_BTAKEOFF )
- {
- err = CheckCloseDoor();
- if ( err != ERR_OK )
- {
- m_displayText->DisplayError(err, m_object);
- return false;
- }
-
- err = m_main->CheckEndMission(false);
- if ( err != ERR_OK )
- {
- m_displayText->DisplayError(err, m_object);
- return false;
- }
-
- FreezeCargo(true); // freeze whole cargo
- m_main->SetMovieLock(true); // blocks everything until the end
- m_main->DeselectAll();
-
- m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE);
- m_event->AddEvent(newEvent);
-
- m_camera->SetType(CAMERA_SCRIPT);
-
- pos = m_pos;
- pos.x -= 110.0f;
- m_terrain->MoveOnFloor(pos);
- pos.y += 10.0f;
- m_camera->SetScriptEye(pos);
- m_posSound = pos;
-
- pos = m_object->RetPosition(0);
- pos.y += 50.0f;
- m_camera->SetScriptLookat(pos);
-
- m_engine->SetFocus(1.0f);
-
- m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP);
-
- m_phase = ABP_CLOSE2;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_DOOR_TIME2;
- return true;
- }
-
- if ( event.event != EVENT_FRAME ) return true;
- if ( m_phase == ABP_WAIT ) return true;
-
- m_progress += event.rTime*m_speed;
-
- if ( m_phase == ABP_LAND )
- {
- if ( m_progress < 1.0f )
- {
- pos = m_pos;
- pos.y += powf(1.0f-m_progress, 2.0f)*300.0f;
- m_object->SetPosition(0, pos);
- MoveCargo(); // all cargo moves
-
- vibCir.z = sinf(m_time*Math::PI* 2.01f)*(Math::PI/150.0f)+
- sinf(m_time*Math::PI* 2.51f)*(Math::PI/200.0f)+
- sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f);
- vibCir.x = sinf(m_time*Math::PI* 2.03f)*(Math::PI/150.0f)+
- sinf(m_time*Math::PI* 2.52f)*(Math::PI/200.0f)+
- sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f);
- vibCir.y = 0.0f;
- vibCir *= Math::Min(1.0f, (1.0f-m_progress)*3.0f);
- m_object->SetCirVibration(vibCir);
-
- pos = m_pos;
- pos.x -= 150.0f;
- m_terrain->MoveOnFloor(pos);
- pos.y += 10.0f;
- m_camera->SetScriptEye(pos);
-
- pos = m_object->RetPosition(0);
- pos.y += 50.0f;
- m_camera->SetScriptLookat(pos);
-
- m_engine->SetFocus(1.0f+(1.0f-m_progress));
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time )
- {
- m_lastParticule = m_time;
-
- // Dust thrown to the ground.
- pos = m_pos;
- pos.x += (Math::Rand()-0.5f)*10.0f;
- pos.z += (Math::Rand()-0.5f)*10.0f;
- angle = Math::Rand()*(Math::PI*2.0f);
- dist = m_progress*50.0f;
- p = Math::RotatePoint(angle, dist);
- speed.x = p.x;
- speed.z = p.y;
- speed.y = 0.0f;
- dim.x = (Math::Rand()*15.0f+15.0f)*m_progress;
- dim.y = dim.x;
- if ( dim.x >= 1.0f )
- {
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f);
- }
-
- // Particles are ejected from the jet engine.
- pos = m_object->RetPosition(0);
- pos.y += 6.0f;
- h = m_terrain->RetFloorHeight(pos)/300.0f;
- speed.x = (Math::Rand()-0.5f)*(80.0f-50.0f*h);
- speed.z = (Math::Rand()-0.5f)*(80.0f-50.0f*h);
- speed.y = -(Math::Rand()*(h+1.0f)*40.0f+(h+1.0f)*40.0f);
- dim.x = Math::Rand()*2.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f);
-
- // Black smoke from the jet engine.
- if ( m_progress > 0.8f )
- {
- pos = m_pos;
- pos.x += (Math::Rand()-0.5f)*8.0f;
- pos.z += (Math::Rand()-0.5f)*8.0f;
- pos.y += 3.0f;
- speed.x = (Math::Rand()-0.5f)*8.0f;
- speed.z = (Math::Rand()-0.5f)*8.0f;
- speed.y = 0.0f;
- dim.x = Math::Rand()*4.0f+4.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f);
- }
- }
- }
- else
- {
- m_bMotor = false; // put out the reactor
-
- m_object->SetPosition(0, m_pos); // setting down
- m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
- MoveCargo(); // all cargo moves
-
- // Impact with the ground.
- max = (int)(50.0f*m_engine->RetParticuleDensity());
- for ( i=0 ; i<max ; i++ )
- {
- angle = Math::Rand()*(Math::PI*2.0f);
- p = Math::RotatePoint(angle, 46.0f);
- pos = m_pos;
- pos.x += p.x;
- pos.z += p.y;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*10.0f+10.0f;
- dim.y = dim.x;
- time = Math::Rand()*2.0f+1.5f;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f);
- }
-
-//? m_camera->StartEffect(CE_CRASH, m_pos, 1.0f);
- m_camera->StartEffect(CE_EXPLO, m_pos, 2.0f);
- m_engine->SetFocus(1.0f);
- m_sound->Play(SOUND_BOUM, m_posSound, 0.6f, 0.5f);
-
- m_phase = ABP_OPENWAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == ABP_OPENWAIT )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time )
- {
- m_lastParticule = m_time;
-
- // Black smoke from the reactor.
- pos = m_pos;
- pos.x += (Math::Rand()-0.5f)*8.0f;
- pos.z += (Math::Rand()-0.5f)*8.0f;
- pos.y += 3.0f;
- speed.x = (Math::Rand()-0.5f)*8.0f;
- speed.z = (Math::Rand()-0.5f)*8.0f;
- speed.y = 0.0f;
- dim.x = Math::Rand()*4.0f+4.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f);
- }
- }
- else
- {
- m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP);
-
- m_phase = ABP_OPEN;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_DOOR_TIME;
- }
- }
-
- if ( m_phase == ABP_OPEN )
- {
- if ( m_progress < 1.0f )
- {
- angle = -m_progress*124.0f*Math::PI/180.0f;
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f+angle);
- }
-
- if ( m_param != PARAM_PORTICO )
- {
- angle = m_progress*Math::PI*2.0f;
- p = Math::RotatePoint(angle, -150.0f);
- pos = m_pos;
- pos.x += p.x;
- pos.z += p.y;
- m_terrain->MoveOnFloor(pos);
- pos.y += 10.0f;
- pos.y += m_progress*40.0f;
- m_camera->SetScriptEye(pos);
-
- m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress);
- }
- }
- else
- {
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
- }
-
- // Clash the doors with the ground.
- max = (int)(20.0f*m_engine->RetParticuleDensity());
- for ( i=0 ; i<max ; i++ )
- {
- angle = Math::Rand()*(20.0f*Math::PI/180.0f)-(10.0f*Math::PI/180.0f);
- angle += (Math::PI/4.0f)*(rand()%8);
- p = Math::RotatePoint(angle, 74.0f);
- pos = m_pos;
- pos.x += p.x;
- pos.z += p.y;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*8.0f+8.0f;
- dim.y = dim.x;
- time = Math::Rand()*2.0f+1.5f;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f);
- }
-
- m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP);
-
- m_phase = ABP_OPEN2;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_DOOR_TIME2;
- }
- }
-
- if ( m_phase == ABP_OPEN2 )
- {
- if ( m_progress < 1.0f )
- {
- len = 7.0f-m_progress*(7.0f+11.5f);
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, len));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -len));
- m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f*m_progress);
- m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f*m_progress);
- }
-
- if ( m_param != PARAM_PORTICO )
- {
- angle = m_progress*Math::PI/2.0f;
- p = Math::RotatePoint(angle, -150.0f);
- pos = m_pos;
- pos.x += p.x;
- pos.z += p.y;
- m_terrain->MoveOnFloor(pos);
- pos.y += 10.0f;
- pos.y += m_progress*40.0f;
- m_camera->SetScriptEye(pos);
-
- m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress);
- }
- }
- else
- {
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f));
- m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
- m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f);
- }
-
- m_phase = ABP_LDWAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ABP_LDWAIT )
- {
- if ( m_progress >= 1.0f )
- {
- FreezeCargo(false); // frees all cargo
-
- if ( m_param != PARAM_PORTICO )
- {
- m_main->SetMovieLock(false); // you can play!
-
- pObj = m_main->RetSelectObject();
- m_main->SelectObject(pObj);
- m_camera->SetObject(pObj);
- if ( pObj == 0 )
- {
- m_camera->SetType(CAMERA_BACK);
- }
- else
- {
- m_camera->SetType(pObj->RetCameraType());
- m_camera->SetDist(pObj->RetCameraDist());
- }
- m_sound->Play(SOUND_BOUM, m_object->RetPosition(0));
- m_soundChannel = -1;
-
- m_engine->SetFogStart(m_fogStart);
- }
-
- m_bOpen = true;
- m_phase = ABP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ABP_CLOSE2 )
- {
- if ( m_progress < 1.0f )
- {
- len = 7.0f-(1.0f-m_progress)*(7.0f+11.5f);
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, len));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -len));
- m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f*(1.0f-m_progress));
- m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f*(1.0f-m_progress));
- }
- }
- else
- {
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, 7.0f));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -7.0f));
- m_object->SetAngleX(10+i, 0.0f);
- m_object->SetAngleX(18+i, 0.0f);
- }
-
- m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP);
-
- m_phase = ABP_CLOSE;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_DOOR_TIME;
- }
- }
-
- if ( m_phase == ABP_CLOSE )
- {
- if ( m_progress < 1.0f )
- {
- angle = -(1.0f-m_progress)*124.0f*Math::PI/180.0f;
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f+angle);
- }
- }
- else
- {
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f);
- }
- m_bMotor = true; // lights the jet engine
-
- // Shock of the closing doors.
- max = (int)(20.0f*m_engine->RetParticuleDensity());
- for ( i=0 ; i<max ; i++ )
- {
- angle = Math::Rand()*Math::PI*2.0f;
- p = Math::RotatePoint(angle, 32.0f);
- pos = m_pos;
- pos.x += p.x;
- pos.z += p.y;
- pos.y += 85.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*3.0f+3.0f;
- dim.y = dim.x;
- time = Math::Rand()*1.0f+1.0f;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time);
- }
- m_sound->Play(SOUND_BOUM, m_object->RetPosition(0));
-
- m_soundChannel = -1;
- m_bOpen = false;
- m_phase = ABP_TOWAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == ABP_TOWAIT )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_soundChannel == -1 )
- {
- m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 0.5f, true);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 2.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 2.0f, BASE_TAKO_TIME, SOPER_STOP);
- }
-
- vibCir.z = sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f);
- vibCir.x = sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f);
- vibCir.y = 0.0f;
- vibCir *= m_progress*1.0f;
- m_object->SetCirVibration(vibCir);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- // Particles are ejected from the reactor.
- pos = m_object->RetPosition(0);
- pos.y += 6.0f;
- speed.x = (Math::Rand()-0.5f)*160.0f;
- speed.z = (Math::Rand()-0.5f)*160.0f;
- speed.y = -(Math::Rand()*10.0f+10.0f);
- dim.x = Math::Rand()*2.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f);
- }
-
- m_engine->SetFogStart(m_fogStart+(0.9f-m_fogStart)*m_progress);
- }
- else
- {
- m_engine->SetFogStart(0.9f);
-
- m_phase = ABP_TAKEOFF;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_TAKO_TIME;
- }
- }
-
- if ( m_phase == ABP_TAKEOFF )
- {
- if ( m_progress < 1.0f )
- {
- pos = m_pos;
- pos.y += powf(m_progress, 2.0f)*600.0f;
- m_object->SetPosition(0, pos);
- MoveCargo(); // all cargo moves
-
- vibCir.z = sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f);
- vibCir.x = sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f);
- vibCir.y = 0.0f;
- m_object->SetCirVibration(vibCir);
-
- pos = m_pos;
- pos.x -= 110.0f+m_progress*250.0f;
- m_terrain->MoveOnFloor(pos);
- pos.y += 10.0f;
- m_camera->SetScriptEye(pos);
-
- pos = m_object->RetPosition(0);
- pos.y += 50.0f;
- m_camera->SetScriptLookat(pos);
-
- m_engine->SetFocus(1.0f+m_progress);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time )
- {
- m_lastParticule = m_time;
-
- // Dust thrown to the ground.
- pos = m_pos;
- pos.x += (Math::Rand()-0.5f)*10.0f;
- pos.z += (Math::Rand()-0.5f)*10.0f;
- angle = Math::Rand()*(Math::PI*2.0f);
- dist = (1.0f-m_progress)*50.0f;
- p = Math::RotatePoint(angle, dist);
- speed.x = p.x;
- speed.z = p.y;
- speed.y = 0.0f;
- dim.x = (Math::Rand()*10.0f+10.0f)*(1.0f-m_progress);
- dim.y = dim.x;
- if ( dim.x >= 1.0f )
- {
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f);
- }
-
- // Particles are ejected from the reactor.
- pos = m_object->RetPosition(0);
- pos.y += 6.0f;
- speed.x = (Math::Rand()-0.5f)*40.0f;
- speed.z = (Math::Rand()-0.5f)*40.0f;
- time = 5.0f+150.0f*m_progress;
- speed.y = -(Math::Rand()*time+time);
- time = 2.0f+m_progress*12.0f;
- dim.x = Math::Rand()*time+time;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f);
-
- // Black smoke from the reactor.
- pos = m_object->RetPosition(0);
- pos.y += 3.0f;
- speed.x = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f);
- speed.z = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f);
- speed.y = 0.0f;
- dim.x = Math::Rand()*20.0f+20.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 10.0f, 0.0f, 2.0f);
- }
- }
- else
- {
- m_soundChannel = -1;
- m_event->MakeEvent(newEvent, EVENT_WIN);
- m_event->AddEvent(newEvent);
-
- m_phase = ABP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == ABP_PORTICO_MOVE ) // advance of the gate?
- {
- if ( m_progress < 1.0f )
- {
- pos = m_object->RetPosition(0);
- pos.z -= event.rTime*5.0f;
- m_object->SetPosition(0, pos);
- MoveCargo(); // all cargo moves
- }
- else
- {
- m_phase = ABP_PORTICO_WAIT1;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ABP_PORTICO_WAIT1 ) // expectation the gate?
- {
- if ( m_progress >= 1.0f )
- {
- m_phase = ABP_PORTICO_DOWN;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_PORTICO_TIME_DOWN;
- }
- }
-
- if ( m_phase == ABP_PORTICO_DOWN ) // down the gate?
- {
- if ( m_progress < 1.0f )
- {
- pos = m_object->RetPosition(0);
- pos.y -= event.rTime*(10.0f/BASE_PORTICO_TIME_DOWN);
- m_object->SetPosition(0, pos);
- MoveCargo(); // all cargo moves
- }
- else
- {
- // Impact with the ground.
- max = (int)(50.0f*m_engine->RetParticuleDensity());
- for ( i=0 ; i<max ; i++ )
- {
- angle = Math::Rand()*(Math::PI*2.0f);
- p = Math::RotatePoint(angle, 46.0f);
- pos = m_pos;
- pos.x += p.x;
- pos.z += p.y;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*10.0f+10.0f;
- dim.y = dim.x;
- time = Math::Rand()*2.0f+1.5f;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f);
- }
-
- m_phase = ABP_PORTICO_WAIT2;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ABP_PORTICO_WAIT2 ) // expectation the gate?
- {
- if ( m_progress >= 1.0f )
- {
- m_phase = ABP_PORTICO_OPEN;
- m_progress = 0.0f;
- m_speed = 1.0f/BASE_PORTICO_TIME_OPEN;
- }
- }
-
- if ( m_phase == ABP_PORTICO_OPEN ) // opening the gate?
- {
- if ( m_progress < 1.0f )
- {
- }
- else
- {
- m_phase = ABP_OPEN;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == ABP_TRANSIT_MOVE ) // transit in space?
- {
- if ( m_progress < 1.0f )
- {
- pos = m_object->RetPosition(0);
- pos.x += event.rTime*(2000.0f/BASE_TRANSIT_TIME);
- m_object->SetPosition(0, pos);
- pos.x += 60.0f;
- m_camera->SetScriptLookat(pos);
- }
- else
- {
- m_object->SetAngleZ(0, 0.0f);
-
- m_param = PARAM_LANDING;
- m_phase = ABP_START;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- EndTransit();
-
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP);
- m_soundChannel = -1;
- }
- goto begin;
- }
- }
-
- if ( m_bMotor )
- {
- if ( m_lastMotorParticule+m_engine->ParticuleAdapt(0.02f) <= m_time )
- {
- m_lastMotorParticule = m_time;
-
- mat = m_object->RetWorldMatrix(0);
-
- if ( event.rTime == 0.0f )
- {
- vSpeed = 0.0f;
- }
- else
- {
- pos = m_object->RetPosition(0);
- if ( m_phase == ABP_TRANSIT_MOVE )
- {
- vSpeed = (pos.x-iPos.x)/event.rTime;
- }
- else
- {
- vSpeed = (pos.y-iPos.y)/event.rTime;
- }
- if ( vSpeed < 0.0f ) vSpeed *= 1.5f;
- }
-
- pos = Math::Vector(0.0f, 6.0f, 0.0f);
- speed.x = (Math::Rand()-0.5f)*4.0f;
- speed.z = (Math::Rand()-0.5f)*4.0f;
- speed.y = vSpeed*0.8f-(8.0f+Math::Rand()*6.0f);
- speed += pos;
- pos = Transform(*mat, pos);
- speed = Transform(*mat, speed);
- speed -= pos;
-
- dim.x = 4.0f+Math::Rand()*4.0f;
- dim.y = dim.x;
-
- m_particule->CreateParticule(pos, speed, dim, PARTIBASE, 3.0f, 0.0f, 0.0f);
-
- if ( m_phase == ABP_TRANSIT_MOVE )
- {
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 12.0f;
- dim.y = dim.x;
- pos = Math::Vector(0.0f, 7.0f, 0.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f);
-
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 4.0f;
- dim.y = dim.x;
- pos = Math::Vector(42.0f, 0.0f, 17.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
- pos = Math::Vector(17.0f, 0.0f, 42.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
- pos = Math::Vector(42.0f, 0.0f, -17.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
- pos = Math::Vector(17.0f, 0.0f, -42.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
- pos = Math::Vector(-42.0f, 0.0f, 17.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
- pos = Math::Vector(-17.0f, 0.0f, 42.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
- pos = Math::Vector(-42.0f, 0.0f, -17.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
- pos = Math::Vector(-17.0f, 0.0f, -42.0f);
- pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f;
- pos = Transform(*mat, pos);
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f);
-
- pos = Math::Vector(42.0f, -2.0f, 17.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[0], pos);
- pos = Math::Vector(17.0f, -2.0f, 42.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[1], pos);
- pos = Math::Vector(42.0f, -2.0f, -17.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[2], pos);
- pos = Math::Vector(17.0f, -2.0f, -42.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[3], pos);
- pos = Math::Vector(-42.0f, -2.0f, 17.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[4], pos);
- pos = Math::Vector(-17.0f, -2.0f, 42.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[5], pos);
- pos = Math::Vector(-42.0f, -2.0f, -17.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[6], pos);
- pos = Math::Vector(-17.0f, -2.0f, -42.0f);
- pos = Transform(*mat, pos);
- m_particule->SetPosition(m_partiChannel[7], pos);
- }
- }
- }
-
- if ( m_soundChannel != -1 )
- {
- pos = m_engine->RetEyePt();
- m_sound->Position(m_soundChannel, pos);
- }
-
- return true;
-}
-
-// Stops the controller.
-
-bool CAutoBase::Abort()
-{
- Event newEvent;
- CObject* pObj;
- int i;
-
- if ( m_phase == ABP_TRANSIT_MOVE ) // transit ?
- {
- m_object->SetAngleZ(0, 0.0f);
-
- m_param = PARAM_LANDING;
- m_phase = ABP_START;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- EndTransit();
-
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP);
- m_soundChannel = -1;
- }
- return true;
- }
-
- if ( m_param == PARAM_PORTICO ) // gate on the porch?
- {
- m_object->SetPosition(0, m_finalPos);
- MoveCargo(); // all cargo moves
-
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
- m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
- m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f);
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f));
- }
- }
- else
- {
- if ( m_phase == ABP_LAND ||
- m_phase == ABP_OPENWAIT ||
- m_phase == ABP_OPEN ||
- m_phase == ABP_OPEN2 ) // Landing?
- {
- m_bMotor = false; // put out the jet engine
- m_bOpen = true;
-
- m_object->SetPosition(0, m_pos); // setting down
- m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
- MoveCargo(); // all cargo moves
- for ( i=0 ; i<8 ; i++ )
- {
- m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
- m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
- m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f);
- m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
- m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f));
- }
-
- m_main->SetMovieLock(false); // you can play!
-
- pObj = m_main->RetSelectObject();
- m_main->SelectObject(pObj);
- m_camera->SetObject(pObj);
- if ( pObj == 0 )
- {
- m_camera->SetType(CAMERA_BACK);
- }
- else
- {
- m_camera->SetType(pObj->RetCameraType());
- m_camera->SetDist(pObj->RetCameraDist());
- }
-
- m_engine->SetFogStart(m_fogStart);
- }
-
- if ( m_phase == ABP_CLOSE2 ||
- m_phase == ABP_CLOSE ||
- m_phase == ABP_TOWAIT ||
- m_phase == ABP_TAKEOFF ) // off?
- {
- m_event->MakeEvent(newEvent, EVENT_WIN);
- m_event->AddEvent(newEvent);
- }
- }
-
- m_object->SetAngleZ(0, 0.0f);
- FreezeCargo(false); // frees all cargo
-
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- m_phase = ABP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoBase::RetError()
-{
- return ERR_OK;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoBase::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, dim, ddim;
- float ox, oy, sx, sy;
- float sleep, delay, magnetic, progress;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- dim.x = 33.0f/640.0f;
- dim.y = 33.0f/480.0f;
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- ddim.x = dim.x*1.5f;
- ddim.y = dim.y*1.5f;
-
-//? pos.x = ox+sx*7.25f;
-//? pos.y = oy+sy*0.25f;
-//? pw->CreateButton(pos, ddim, 63, EVENT_OBJECT_BHELP);
-
- pos.x = ox+sx*8.00f;
- pos.y = oy+sy*0.25f;
- pw->CreateButton(pos, ddim, 28, EVENT_OBJECT_BTAKEOFF);
-
- if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) )
- {
- pos.x = ox+sx*10.2f;
- pos.y = oy+sy*0.5f;
- ddim.x = dim.x*1.0f;
- ddim.y = dim.y*1.0f;
- pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT);
- }
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 100, EVENT_OBJECT_TYPE);
-
- UpdateInterface();
-
- return true;
-}
-
-// Updates the status of all interface buttons.
-
-void CAutoBase::UpdateInterface()
-{
- CWindow* pw;
-
- if ( !m_object->RetSelect() ) return;
-
- CAuto::UpdateInterface();
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
-}
-
-
-// Freeze or frees all cargo.
-
-void CAutoBase::FreezeCargo(bool bFreeze)
-{
- CObject* pObj;
- CPhysics* physics;
- Math::Vector oPos;
- float dist;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- pObj->SetCargo(false);
-
- if ( pObj == m_object ) continue; // yourself?
- if ( pObj->RetTruck() != 0 ) continue; // transport object?
-
- oPos = pObj->RetPosition(0);
- dist = Math::DistanceProjected(m_pos, oPos);
- if ( dist < 32.0f )
- {
- if ( bFreeze )
- {
- pObj->SetCargo(true);
- }
-
- physics = pObj->RetPhysics();
- if ( physics != 0 )
- {
- physics->SetFreeze(bFreeze);
- }
- }
- }
-}
-
-// All cargo moves vertically with the ship.
-
-void CAutoBase::MoveCargo()
-{
- CObject* pObj;
- Math::Vector oPos, sPos;
- int i;
-
- sPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( !pObj->RetCargo() ) continue;
-
- oPos = pObj->RetPosition(0);
- oPos.y = sPos.y+30.0f;
- oPos.y += pObj->RetCharacter()->height;
- oPos.x += sPos.x-m_lastPos.x;
- oPos.z += sPos.z-m_lastPos.z;
- pObj->SetPosition(0, oPos);
- }
-
- m_lastPos = sPos;
-}
-
-
-// Checks whether it is possible to close the doors.
-
-Error CAutoBase::CheckCloseDoor()
-{
- CObject* pObj;
- Math::Vector oPos;
- ObjectType type;
- float oRad, dist;
- int i, j;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj == m_object ) continue; // yourself?
- if ( !pObj->RetActif() ) continue; // inactive?
-
- type = pObj->RetType();
- if ( type == OBJECT_PORTICO ) continue;
-
- j = 0;
- while ( pObj->GetCrashSphere(j++, oPos, oRad) )
- {
- dist = Math::DistanceProjected(m_pos, oPos);
- if ( dist+oRad > 32.0f &&
- dist-oRad < 72.0f )
- {
- return ERR_BASE_DLOCK;
- }
-
- if ( type == OBJECT_HUMAN &&
- dist+oRad > 32.0f )
- {
- return ERR_BASE_DHUMAN;
- }
- }
- }
- return ERR_OK;
-}
-
-
-// Start a transit.
-
-void CAutoBase::BeginTransit()
-{
- bool bFull, bQuarter;
-
- if ( m_param == PARAM_TRANSIT2 )
- {
- strcpy(m_bgBack, "back01.tga"); // clouds orange / blue
- }
- else if ( m_param == PARAM_TRANSIT3 )
- {
- strcpy(m_bgBack, "back22.tga"); // blueberries clouds
- }
- else
- {
-#if _DEMO
- strcpy(m_bgBack, "back46b.tga"); // paintings
-#else
- strcpy(m_bgBack, "back46.tga"); // paintings
-#endif
- }
-
- m_engine->SetFogStart(0.9f); // hardly any fog
- m_engine->SetDeepView(2000.0f); // we see very far
- m_engine->ApplyChange();
-
- m_engine->RetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, bFull, bQuarter);
- m_engine->FreeTexture(m_bgName);
-
- m_engine->SetBackground(m_bgBack, 0x00000000, 0x00000000, 0x00000000, 0x00000000);
- m_engine->LoadTexture(m_bgBack);
-
- m_cloud->SetEnable(false); // cache clouds
- m_planet->SetMode(1);
-}
-
-// End of a transit.
-
-void CAutoBase::EndTransit()
-{
- m_engine->SetFogStart(m_fogStart); // gives initial fog
- m_engine->SetDeepView(m_deepView); // gives initial depth
- m_engine->ApplyChange();
-
- m_engine->FreeTexture(m_bgBack);
-
- m_engine->SetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown);
- m_engine->LoadTexture(m_bgName);
-
- m_cloud->SetEnable(true); // gives the clouds
- m_planet->SetMode(0);
-
- m_main->StartMusic();
-}
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autobase.h" + +#include "common/iman.h" +#include "old/terrain.h" +#include "old/cloud.h" +#include "old/planet.h" +#include "old/blitz.h" +#include "math/geometry.h" +#include "object/robotmain.h" +#include "physics/physics.h" +#include "ui/interface.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + +const float BASE_LAND_TIME = 7.5f; // hard landing +const float BASE_TAKO_TIME = 10.0f; // hard landing +const float BASE_DOOR_TIME = 6.0f; // time opening / closing +const float BASE_DOOR_TIME2 = 2.0f; // time opening / closing suppl. +const float BASE_PORTICO_TIME_MOVE = 16.0f; // gate advance time +const float BASE_PORTICO_TIME_DOWN = 4.0f; // gate length down +const float BASE_PORTICO_TIME_OPEN = 4.0f; // gate opening duration +const float BASE_TRANSIT_TIME = 15.0f; // transit duration + + + + +// Object's constructor. + +CAutoBase::CAutoBase(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + m_fogStart = m_engine->RetFogStart(); + m_deepView = m_engine->RetDeepView(); + Init(); + m_phase = ABP_WAIT; + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoBase::~CAutoBase() +{ +} + + +// Destroys the object. + +void CAutoBase::DeleteObject(bool bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoBase::Init() +{ + m_bOpen = false; + m_time = 0.0f; + m_lastParticule = 0.0f; + m_lastMotorParticule = 0.0f; + + m_pos = m_object->RetPosition(0); + m_lastPos = m_pos; + + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; +} + + +// Start the object. + +void CAutoBase::Start(int param) +{ + m_phase = ABP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_param = param; +} + + +// Management of an event. + +bool CAutoBase::EventProcess(const Event &event) +{ + Math::Matrix* mat; + Event newEvent; + CObject* pObj; + Math::Vector pos, speed, vibCir, iPos; + Math::Point dim, p; + Error err; + float angle, dist, time, h, len, vSpeed; + int i, max; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + +begin: + iPos = m_object->RetPosition(0); + + if ( m_phase == ABP_START ) + { + if ( m_param != PARAM_STOP && // not placed on the ground? + m_param != PARAM_FIXSCENE ) + { + FreezeCargo(true); // freeze whole cargo + } + + if ( m_param == PARAM_STOP ) // raises the ground? + { + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f); + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f)); + } + + pObj = m_main->RetSelectObject(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + if ( pObj == 0 ) + { + m_camera->SetType(CAMERA_BACK); + } + else + { + m_camera->SetType(pObj->RetCameraType()); + m_camera->SetDist(pObj->RetCameraDist()); + } + + m_main->StartMusic(); + } + + if ( m_param == PARAM_FIXSCENE ) // raises the ground? + { + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f); + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f)); + } + } + + if ( m_param == PARAM_LANDING ) // Landing? + { + m_phase = ABP_LAND; + m_progress = 0.0f; + m_speed = 1.0f/BASE_LAND_TIME; + + m_main->SetMovieLock(true); // blocks everything until the end of the landing + m_bMotor = true; // lights the jet engine + + m_camera->SetType(CAMERA_SCRIPT); + + pos = m_pos; + pos.x -= 150.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + m_posSound = pos; + + pos = m_object->RetPosition(0); + pos.y += 300.0f+50.0f; + m_camera->SetScriptLookat(pos); + + m_camera->FixCamera(); + m_engine->SetFocus(2.0f); + + m_engine->SetFogStart(0.9f); + + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.3f, 2.0f, true); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, BASE_LAND_TIME, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 2.0f, SOPER_STOP); + } + + m_main->StartMusic(); + } + + if ( m_param == PARAM_PORTICO ) // gate on the porch? + { + pos = m_object->RetPosition(0); + m_finalPos = pos; + pos.z += BASE_PORTICO_TIME_MOVE*5.0f; // back + pos.y += 10.0f; // rises (the gate) + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + + m_phase = ABP_PORTICO_MOVE; + m_progress = 0.0f; + m_speed = 1.0f/BASE_PORTICO_TIME_MOVE; + + m_main->StartMusic(); + } + + if ( m_param == PARAM_TRANSIT1 || + m_param == PARAM_TRANSIT2 || + m_param == PARAM_TRANSIT3 ) // transit in space? + { + m_phase = ABP_TRANSIT_MOVE; + m_progress = 0.0f; + m_speed = 1.0f/BASE_TRANSIT_TIME; + + m_object->SetAngleZ(0, -Math::PI/2.0f); + pos = m_object->RetPosition(0); + pos.y += 10000.0f; // in space + m_finalPos = pos; + m_object->SetPosition(0, pos); + + m_main->SetMovieLock(true); // blocks everything until the end of the landing + m_bMotor = true; // lights the jet engine + + m_camera->SetType(CAMERA_SCRIPT); + pos.x += 1000.0f; + pos.z -= 60.0f; + pos.y += 80.0f; + m_camera->SetScriptEye(pos); + m_posSound = pos; + m_camera->FixCamera(); + m_engine->SetFocus(1.0f); + + BeginTransit(); + + mat = m_object->RetWorldMatrix(0); + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 10.0f; + dim.y = dim.x; + pos = Math::Vector(42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_partiChannel[0] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = Math::Vector(17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_partiChannel[1] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = Math::Vector(42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_partiChannel[2] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = Math::Vector(17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_partiChannel[3] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = Math::Vector(-42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_partiChannel[4] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = Math::Vector(-17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_partiChannel[5] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = Math::Vector(-42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_partiChannel[6] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + pos = Math::Vector(-17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_partiChannel[7] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 1.2f, true); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, BASE_TRANSIT_TIME*0.55f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.8f, BASE_TRANSIT_TIME*0.45f, SOPER_STOP); + } + } + } + + if ( event.event == EVENT_UPDINTERFACE ) + { + if ( m_object->RetSelect() ) CreateInterface(true); + } + + if ( event.event == EVENT_OBJECT_BTAKEOFF ) + { + err = CheckCloseDoor(); + if ( err != ERR_OK ) + { + m_displayText->DisplayError(err, m_object); + return false; + } + + err = m_main->CheckEndMission(false); + if ( err != ERR_OK ) + { + m_displayText->DisplayError(err, m_object); + return false; + } + + FreezeCargo(true); // freeze whole cargo + m_main->SetMovieLock(true); // blocks everything until the end + m_main->DeselectAll(); + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + + m_camera->SetType(CAMERA_SCRIPT); + + pos = m_pos; + pos.x -= 110.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + m_posSound = pos; + + pos = m_object->RetPosition(0); + pos.y += 50.0f; + m_camera->SetScriptLookat(pos); + + m_engine->SetFocus(1.0f); + + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, true); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP); + + m_phase = ABP_CLOSE2; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME2; + return true; + } + + if ( event.event != EVENT_FRAME ) return true; + if ( m_phase == ABP_WAIT ) return true; + + m_progress += event.rTime*m_speed; + + if ( m_phase == ABP_LAND ) + { + if ( m_progress < 1.0f ) + { + pos = m_pos; + pos.y += powf(1.0f-m_progress, 2.0f)*300.0f; + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + + vibCir.z = sinf(m_time*Math::PI* 2.01f)*(Math::PI/150.0f)+ + sinf(m_time*Math::PI* 2.51f)*(Math::PI/200.0f)+ + sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f); + vibCir.x = sinf(m_time*Math::PI* 2.03f)*(Math::PI/150.0f)+ + sinf(m_time*Math::PI* 2.52f)*(Math::PI/200.0f)+ + sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f); + vibCir.y = 0.0f; + vibCir *= Math::Min(1.0f, (1.0f-m_progress)*3.0f); + m_object->SetCirVibration(vibCir); + + pos = m_pos; + pos.x -= 150.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + + pos = m_object->RetPosition(0); + pos.y += 50.0f; + m_camera->SetScriptLookat(pos); + + m_engine->SetFocus(1.0f+(1.0f-m_progress)); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + // Dust thrown to the ground. + pos = m_pos; + pos.x += (Math::Rand()-0.5f)*10.0f; + pos.z += (Math::Rand()-0.5f)*10.0f; + angle = Math::Rand()*(Math::PI*2.0f); + dist = m_progress*50.0f; + p = Math::RotatePoint(angle, dist); + speed.x = p.x; + speed.z = p.y; + speed.y = 0.0f; + dim.x = (Math::Rand()*15.0f+15.0f)*m_progress; + dim.y = dim.x; + if ( dim.x >= 1.0f ) + { + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); + } + + // Particles are ejected from the jet engine. + pos = m_object->RetPosition(0); + pos.y += 6.0f; + h = m_terrain->RetFloorHeight(pos)/300.0f; + speed.x = (Math::Rand()-0.5f)*(80.0f-50.0f*h); + speed.z = (Math::Rand()-0.5f)*(80.0f-50.0f*h); + speed.y = -(Math::Rand()*(h+1.0f)*40.0f+(h+1.0f)*40.0f); + dim.x = Math::Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + + // Black smoke from the jet engine. + if ( m_progress > 0.8f ) + { + pos = m_pos; + pos.x += (Math::Rand()-0.5f)*8.0f; + pos.z += (Math::Rand()-0.5f)*8.0f; + pos.y += 3.0f; + speed.x = (Math::Rand()-0.5f)*8.0f; + speed.z = (Math::Rand()-0.5f)*8.0f; + speed.y = 0.0f; + dim.x = Math::Rand()*4.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); + } + } + } + else + { + m_bMotor = false; // put out the reactor + + m_object->SetPosition(0, m_pos); // setting down + m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f)); + MoveCargo(); // all cargo moves + + // Impact with the ground. + max = (int)(50.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; i<max ; i++ ) + { + angle = Math::Rand()*(Math::PI*2.0f); + p = Math::RotatePoint(angle, 46.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*10.0f+10.0f; + dim.y = dim.x; + time = Math::Rand()*2.0f+1.5f; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + } + +//? m_camera->StartEffect(CE_CRASH, m_pos, 1.0f); + m_camera->StartEffect(CE_EXPLO, m_pos, 2.0f); + m_engine->SetFocus(1.0f); + m_sound->Play(SOUND_BOUM, m_posSound, 0.6f, 0.5f); + + m_phase = ABP_OPENWAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_OPENWAIT ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + // Black smoke from the reactor. + pos = m_pos; + pos.x += (Math::Rand()-0.5f)*8.0f; + pos.z += (Math::Rand()-0.5f)*8.0f; + pos.y += 3.0f; + speed.x = (Math::Rand()-0.5f)*8.0f; + speed.z = (Math::Rand()-0.5f)*8.0f; + speed.y = 0.0f; + dim.x = Math::Rand()*4.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); + } + } + else + { + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, true); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); + + m_phase = ABP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME; + } + } + + if ( m_phase == ABP_OPEN ) + { + if ( m_progress < 1.0f ) + { + angle = -m_progress*124.0f*Math::PI/180.0f; + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f+angle); + } + + if ( m_param != PARAM_PORTICO ) + { + angle = m_progress*Math::PI*2.0f; + p = Math::RotatePoint(angle, -150.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + pos.y += m_progress*40.0f; + m_camera->SetScriptEye(pos); + + m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f); + } + + // Clash the doors with the ground. + max = (int)(20.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; i<max ; i++ ) + { + angle = Math::Rand()*(20.0f*Math::PI/180.0f)-(10.0f*Math::PI/180.0f); + angle += (Math::PI/4.0f)*(rand()%8); + p = Math::RotatePoint(angle, 74.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*8.0f+8.0f; + dim.y = dim.x; + time = Math::Rand()*2.0f+1.5f; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + } + + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, true); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP); + + m_phase = ABP_OPEN2; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME2; + } + } + + if ( m_phase == ABP_OPEN2 ) + { + if ( m_progress < 1.0f ) + { + len = 7.0f-m_progress*(7.0f+11.5f); + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, len)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -len)); + m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f*m_progress); + m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f*m_progress); + } + + if ( m_param != PARAM_PORTICO ) + { + angle = m_progress*Math::PI/2.0f; + p = Math::RotatePoint(angle, -150.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + pos.y += m_progress*40.0f; + m_camera->SetScriptEye(pos); + + m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f)); + m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f); + } + + m_phase = ABP_LDWAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_LDWAIT ) + { + if ( m_progress >= 1.0f ) + { + FreezeCargo(false); // frees all cargo + + if ( m_param != PARAM_PORTICO ) + { + m_main->SetMovieLock(false); // you can play! + + pObj = m_main->RetSelectObject(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + if ( pObj == 0 ) + { + m_camera->SetType(CAMERA_BACK); + } + else + { + m_camera->SetType(pObj->RetCameraType()); + m_camera->SetDist(pObj->RetCameraDist()); + } + m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); + m_soundChannel = -1; + + m_engine->SetFogStart(m_fogStart); + } + + m_bOpen = true; + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_CLOSE2 ) + { + if ( m_progress < 1.0f ) + { + len = 7.0f-(1.0f-m_progress)*(7.0f+11.5f); + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, len)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -len)); + m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f*(1.0f-m_progress)); + m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f*(1.0f-m_progress)); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, 7.0f)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -7.0f)); + m_object->SetAngleX(10+i, 0.0f); + m_object->SetAngleX(18+i, 0.0f); + } + + m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, true); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); + + m_phase = ABP_CLOSE; + m_progress = 0.0f; + m_speed = 1.0f/BASE_DOOR_TIME; + } + } + + if ( m_phase == ABP_CLOSE ) + { + if ( m_progress < 1.0f ) + { + angle = -(1.0f-m_progress)*124.0f*Math::PI/180.0f; + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f+angle); + } + } + else + { + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f); + } + m_bMotor = true; // lights the jet engine + + // Shock of the closing doors. + max = (int)(20.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; i<max ; i++ ) + { + angle = Math::Rand()*Math::PI*2.0f; + p = Math::RotatePoint(angle, 32.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + pos.y += 85.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*3.0f+3.0f; + dim.y = dim.x; + time = Math::Rand()*1.0f+1.0f; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time); + } + m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); + + m_soundChannel = -1; + m_bOpen = false; + m_phase = ABP_TOWAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_TOWAIT ) + { + if ( m_progress < 1.0f ) + { + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 0.5f, true); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 2.0f, BASE_TAKO_TIME, SOPER_STOP); + } + + vibCir.z = sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f); + vibCir.x = sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f); + vibCir.y = 0.0f; + vibCir *= m_progress*1.0f; + m_object->SetCirVibration(vibCir); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + // Particles are ejected from the reactor. + pos = m_object->RetPosition(0); + pos.y += 6.0f; + speed.x = (Math::Rand()-0.5f)*160.0f; + speed.z = (Math::Rand()-0.5f)*160.0f; + speed.y = -(Math::Rand()*10.0f+10.0f); + dim.x = Math::Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + } + + m_engine->SetFogStart(m_fogStart+(0.9f-m_fogStart)*m_progress); + } + else + { + m_engine->SetFogStart(0.9f); + + m_phase = ABP_TAKEOFF; + m_progress = 0.0f; + m_speed = 1.0f/BASE_TAKO_TIME; + } + } + + if ( m_phase == ABP_TAKEOFF ) + { + if ( m_progress < 1.0f ) + { + pos = m_pos; + pos.y += powf(m_progress, 2.0f)*600.0f; + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + + vibCir.z = sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f); + vibCir.x = sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f); + vibCir.y = 0.0f; + m_object->SetCirVibration(vibCir); + + pos = m_pos; + pos.x -= 110.0f+m_progress*250.0f; + m_terrain->MoveOnFloor(pos); + pos.y += 10.0f; + m_camera->SetScriptEye(pos); + + pos = m_object->RetPosition(0); + pos.y += 50.0f; + m_camera->SetScriptLookat(pos); + + m_engine->SetFocus(1.0f+m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + // Dust thrown to the ground. + pos = m_pos; + pos.x += (Math::Rand()-0.5f)*10.0f; + pos.z += (Math::Rand()-0.5f)*10.0f; + angle = Math::Rand()*(Math::PI*2.0f); + dist = (1.0f-m_progress)*50.0f; + p = Math::RotatePoint(angle, dist); + speed.x = p.x; + speed.z = p.y; + speed.y = 0.0f; + dim.x = (Math::Rand()*10.0f+10.0f)*(1.0f-m_progress); + dim.y = dim.x; + if ( dim.x >= 1.0f ) + { + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); + } + + // Particles are ejected from the reactor. + pos = m_object->RetPosition(0); + pos.y += 6.0f; + speed.x = (Math::Rand()-0.5f)*40.0f; + speed.z = (Math::Rand()-0.5f)*40.0f; + time = 5.0f+150.0f*m_progress; + speed.y = -(Math::Rand()*time+time); + time = 2.0f+m_progress*12.0f; + dim.x = Math::Rand()*time+time; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + + // Black smoke from the reactor. + pos = m_object->RetPosition(0); + pos.y += 3.0f; + speed.x = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); + speed.z = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); + speed.y = 0.0f; + dim.x = Math::Rand()*20.0f+20.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 10.0f, 0.0f, 2.0f); + } + } + else + { + m_soundChannel = -1; + m_event->MakeEvent(newEvent, EVENT_WIN); + m_event->AddEvent(newEvent); + + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_PORTICO_MOVE ) // advance of the gate? + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.z -= event.rTime*5.0f; + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + } + else + { + m_phase = ABP_PORTICO_WAIT1; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_PORTICO_WAIT1 ) // expectation the gate? + { + if ( m_progress >= 1.0f ) + { + m_phase = ABP_PORTICO_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/BASE_PORTICO_TIME_DOWN; + } + } + + if ( m_phase == ABP_PORTICO_DOWN ) // down the gate? + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.y -= event.rTime*(10.0f/BASE_PORTICO_TIME_DOWN); + m_object->SetPosition(0, pos); + MoveCargo(); // all cargo moves + } + else + { + // Impact with the ground. + max = (int)(50.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; i<max ; i++ ) + { + angle = Math::Rand()*(Math::PI*2.0f); + p = Math::RotatePoint(angle, 46.0f); + pos = m_pos; + pos.x += p.x; + pos.z += p.y; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*10.0f+10.0f; + dim.y = dim.x; + time = Math::Rand()*2.0f+1.5f; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + } + + m_phase = ABP_PORTICO_WAIT2; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ABP_PORTICO_WAIT2 ) // expectation the gate? + { + if ( m_progress >= 1.0f ) + { + m_phase = ABP_PORTICO_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/BASE_PORTICO_TIME_OPEN; + } + } + + if ( m_phase == ABP_PORTICO_OPEN ) // opening the gate? + { + if ( m_progress < 1.0f ) + { + } + else + { + m_phase = ABP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ABP_TRANSIT_MOVE ) // transit in space? + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.x += event.rTime*(2000.0f/BASE_TRANSIT_TIME); + m_object->SetPosition(0, pos); + pos.x += 60.0f; + m_camera->SetScriptLookat(pos); + } + else + { + m_object->SetAngleZ(0, 0.0f); + + m_param = PARAM_LANDING; + m_phase = ABP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + EndTransit(); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP); + m_soundChannel = -1; + } + goto begin; + } + } + + if ( m_bMotor ) + { + if ( m_lastMotorParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) + { + m_lastMotorParticule = m_time; + + mat = m_object->RetWorldMatrix(0); + + if ( event.rTime == 0.0f ) + { + vSpeed = 0.0f; + } + else + { + pos = m_object->RetPosition(0); + if ( m_phase == ABP_TRANSIT_MOVE ) + { + vSpeed = (pos.x-iPos.x)/event.rTime; + } + else + { + vSpeed = (pos.y-iPos.y)/event.rTime; + } + if ( vSpeed < 0.0f ) vSpeed *= 1.5f; + } + + pos = Math::Vector(0.0f, 6.0f, 0.0f); + speed.x = (Math::Rand()-0.5f)*4.0f; + speed.z = (Math::Rand()-0.5f)*4.0f; + speed.y = vSpeed*0.8f-(8.0f+Math::Rand()*6.0f); + speed += pos; + pos = Transform(*mat, pos); + speed = Transform(*mat, speed); + speed -= pos; + + dim.x = 4.0f+Math::Rand()*4.0f; + dim.y = dim.x; + + m_particule->CreateParticule(pos, speed, dim, PARTIBASE, 3.0f, 0.0f, 0.0f); + + if ( m_phase == ABP_TRANSIT_MOVE ) + { + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 12.0f; + dim.y = dim.x; + pos = Math::Vector(0.0f, 7.0f, 0.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); + + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 4.0f; + dim.y = dim.x; + pos = Math::Vector(42.0f, 0.0f, 17.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = Math::Vector(17.0f, 0.0f, 42.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = Math::Vector(42.0f, 0.0f, -17.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = Math::Vector(17.0f, 0.0f, -42.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = Math::Vector(-42.0f, 0.0f, 17.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = Math::Vector(-17.0f, 0.0f, 42.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = Math::Vector(-42.0f, 0.0f, -17.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + pos = Math::Vector(-17.0f, 0.0f, -42.0f); + pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; + pos = Transform(*mat, pos); + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + + pos = Math::Vector(42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[0], pos); + pos = Math::Vector(17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[1], pos); + pos = Math::Vector(42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[2], pos); + pos = Math::Vector(17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[3], pos); + pos = Math::Vector(-42.0f, -2.0f, 17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[4], pos); + pos = Math::Vector(-17.0f, -2.0f, 42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[5], pos); + pos = Math::Vector(-42.0f, -2.0f, -17.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[6], pos); + pos = Math::Vector(-17.0f, -2.0f, -42.0f); + pos = Transform(*mat, pos); + m_particule->SetPosition(m_partiChannel[7], pos); + } + } + } + + if ( m_soundChannel != -1 ) + { + pos = m_engine->RetEyePt(); + m_sound->Position(m_soundChannel, pos); + } + + return true; +} + +// Stops the controller. + +bool CAutoBase::Abort() +{ + Event newEvent; + CObject* pObj; + int i; + + if ( m_phase == ABP_TRANSIT_MOVE ) // transit ? + { + m_object->SetAngleZ(0, 0.0f); + + m_param = PARAM_LANDING; + m_phase = ABP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + EndTransit(); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP); + m_soundChannel = -1; + } + return true; + } + + if ( m_param == PARAM_PORTICO ) // gate on the porch? + { + m_object->SetPosition(0, m_finalPos); + MoveCargo(); // all cargo moves + + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f); + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f)); + } + } + else + { + if ( m_phase == ABP_LAND || + m_phase == ABP_OPENWAIT || + m_phase == ABP_OPEN || + m_phase == ABP_OPEN2 ) // Landing? + { + m_bMotor = false; // put out the jet engine + m_bOpen = true; + + m_object->SetPosition(0, m_pos); // setting down + m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f)); + MoveCargo(); // all cargo moves + for ( i=0 ; i<8 ; i++ ) + { + m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f); + m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f); + m_object->SetAngleX(18+i, 10.0f*Math::PI/180.0f); + m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f)); + m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f)); + } + + m_main->SetMovieLock(false); // you can play! + + pObj = m_main->RetSelectObject(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + if ( pObj == 0 ) + { + m_camera->SetType(CAMERA_BACK); + } + else + { + m_camera->SetType(pObj->RetCameraType()); + m_camera->SetDist(pObj->RetCameraDist()); + } + + m_engine->SetFogStart(m_fogStart); + } + + if ( m_phase == ABP_CLOSE2 || + m_phase == ABP_CLOSE || + m_phase == ABP_TOWAIT || + m_phase == ABP_TAKEOFF ) // off? + { + m_event->MakeEvent(newEvent, EVENT_WIN); + m_event->AddEvent(newEvent); + } + } + + m_object->SetAngleZ(0, 0.0f); + FreezeCargo(false); // frees all cargo + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_phase = ABP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoBase::RetError() +{ + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +bool CAutoBase::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, dim, ddim; + float ox, oy, sx, sy; + float sleep, delay, magnetic, progress; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + ddim.x = dim.x*1.5f; + ddim.y = dim.y*1.5f; + +//? pos.x = ox+sx*7.25f; +//? pos.y = oy+sy*0.25f; +//? pw->CreateButton(pos, ddim, 63, EVENT_OBJECT_BHELP); + + pos.x = ox+sx*8.00f; + pos.y = oy+sy*0.25f; + pw->CreateButton(pos, ddim, 28, EVENT_OBJECT_BTAKEOFF); + + if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) ) + { + pos.x = ox+sx*10.2f; + pos.y = oy+sy*0.5f; + ddim.x = dim.x*1.0f; + ddim.y = dim.y*1.0f; + pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); + } + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 100, EVENT_OBJECT_TYPE); + + UpdateInterface(); + + return true; +} + +// Updates the status of all interface buttons. + +void CAutoBase::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); +} + + +// Freeze or frees all cargo. + +void CAutoBase::FreezeCargo(bool bFreeze) +{ + CObject* pObj; + CPhysics* physics; + Math::Vector oPos; + float dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + pObj->SetCargo(false); + + if ( pObj == m_object ) continue; // yourself? + if ( pObj->RetTruck() != 0 ) continue; // transport object? + + oPos = pObj->RetPosition(0); + dist = Math::DistanceProjected(m_pos, oPos); + if ( dist < 32.0f ) + { + if ( bFreeze ) + { + pObj->SetCargo(true); + } + + physics = pObj->RetPhysics(); + if ( physics != 0 ) + { + physics->SetFreeze(bFreeze); + } + } + } +} + +// All cargo moves vertically with the ship. + +void CAutoBase::MoveCargo() +{ + CObject* pObj; + Math::Vector oPos, sPos; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetCargo() ) continue; + + oPos = pObj->RetPosition(0); + oPos.y = sPos.y+30.0f; + oPos.y += pObj->RetCharacter()->height; + oPos.x += sPos.x-m_lastPos.x; + oPos.z += sPos.z-m_lastPos.z; + pObj->SetPosition(0, oPos); + } + + m_lastPos = sPos; +} + + +// Checks whether it is possible to close the doors. + +Error CAutoBase::CheckCloseDoor() +{ + CObject* pObj; + Math::Vector oPos; + ObjectType type; + float oRad, dist; + int i, j; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj == m_object ) continue; // yourself? + if ( !pObj->RetActif() ) continue; // inactive? + + type = pObj->RetType(); + if ( type == OBJECT_PORTICO ) continue; + + j = 0; + while ( pObj->GetCrashSphere(j++, oPos, oRad) ) + { + dist = Math::DistanceProjected(m_pos, oPos); + if ( dist+oRad > 32.0f && + dist-oRad < 72.0f ) + { + return ERR_BASE_DLOCK; + } + + if ( type == OBJECT_HUMAN && + dist+oRad > 32.0f ) + { + return ERR_BASE_DHUMAN; + } + } + } + return ERR_OK; +} + + +// Start a transit. + +void CAutoBase::BeginTransit() +{ + bool bFull, bQuarter; + + if ( m_param == PARAM_TRANSIT2 ) + { + strcpy(m_bgBack, "back01.tga"); // clouds orange / blue + } + else if ( m_param == PARAM_TRANSIT3 ) + { + strcpy(m_bgBack, "back22.tga"); // blueberries clouds + } + else + { +#if _DEMO + strcpy(m_bgBack, "back46b.tga"); // paintings +#else + strcpy(m_bgBack, "back46.tga"); // paintings +#endif + } + + m_engine->SetFogStart(0.9f); // hardly any fog + m_engine->SetDeepView(2000.0f); // we see very far + m_engine->ApplyChange(); + + m_engine->RetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, bFull, bQuarter); + m_engine->FreeTexture(m_bgName); + + m_engine->SetBackground(m_bgBack, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + m_engine->LoadTexture(m_bgBack); + + m_cloud->SetEnable(false); // cache clouds + m_planet->SetMode(1); +} + +// End of a transit. + +void CAutoBase::EndTransit() +{ + m_engine->SetFogStart(m_fogStart); // gives initial fog + m_engine->SetDeepView(m_deepView); // gives initial depth + m_engine->ApplyChange(); + + m_engine->FreeTexture(m_bgBack); + + m_engine->SetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown); + m_engine->LoadTexture(m_bgName); + + m_cloud->SetEnable(true); // gives the clouds + m_planet->SetMode(0); + + m_main->StartMusic(); +} + diff --git a/src/object/auto/autobase.h b/src/object/auto/autobase.h index 0f71ef6..eb47a93 100644 --- a/src/object/auto/autobase.h +++ b/src/object/auto/autobase.h @@ -1,112 +1,112 @@ -// * 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/.
-
-// autobase.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoBaseParam
-{
- PARAM_STOP = 0, // run=0 -> stops and open
- PARAM_LANDING = 1, // run=1 -> landing
- PARAM_PORTICO = 2, // run=2 -> gate on the ground
- PARAM_FIXSCENE = 3, // run=3 -> open and stops to win / lost
- PARAM_TRANSIT1 = 11, // run=11 -> transit in space
- PARAM_TRANSIT2 = 12, // run=12 -> transit in space
- PARAM_TRANSIT3 = 13 // run=13 -> transit in space
-};
-
-enum AutoBasePhase
-{
- ABP_WAIT = 1, // expected
- ABP_START = 2, // start-up
-
- ABP_LAND = 3, // landing
- ABP_OPENWAIT = 4, // wait before opening
- ABP_OPEN = 5, // opens the gate
- ABP_OPEN2 = 6, // opens supplements
- ABP_LDWAIT = 7, // expected
-
- ABP_CLOSE2 = 8, // closes supplements
- ABP_CLOSE = 9, // closes gate
- ABP_TOWAIT = 10, // wait before takeoff
- ABP_TAKEOFF = 11, // take-off
-
- ABP_PORTICO_MOVE = 12, // gate advance
- ABP_PORTICO_WAIT1= 13, // gate expected
- ABP_PORTICO_DOWN = 14, // gate down
- ABP_PORTICO_WAIT2= 15, // gate expected
- ABP_PORTICO_OPEN = 16, // gate opens
-
- ABP_TRANSIT_MOVE = 17, // transit - moving
-};
-
-
-
-class CAutoBase : public CAuto
-{
-public:
- CAutoBase(CInstanceManager* iMan, CObject* object);
- ~CAutoBase();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- void Start(int param);
- bool EventProcess(const Event &event);
- bool Abort();
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
-protected:
- void UpdateInterface();
- void FreezeCargo(bool bFreeze);
- void MoveCargo();
- Error CheckCloseDoor();
- void BeginTransit();
- void EndTransit();
-
-protected:
- AutoBasePhase m_phase;
- bool m_bOpen;
- float m_progress;
- float m_speed;
- float m_lastParticule;
- float m_lastMotorParticule;
- float m_fogStart;
- float m_deepView;
- Math::Vector m_pos;
- Math::Vector m_posSound;
- Math::Vector m_finalPos;
- Math::Vector m_lastPos;
- int m_param;
- int m_soundChannel;
- int m_partiChannel[8];
-
- char m_bgBack[100];
- char m_bgName[100];
- D3DCOLOR m_bgUp;
- D3DCOLOR m_bgDown;
- D3DCOLOR m_bgCloudUp;
- D3DCOLOR m_bgCloudDown;
-};
-
+// * 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/. + +// autobase.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoBaseParam +{ + PARAM_STOP = 0, // run=0 -> stops and open + PARAM_LANDING = 1, // run=1 -> landing + PARAM_PORTICO = 2, // run=2 -> gate on the ground + PARAM_FIXSCENE = 3, // run=3 -> open and stops to win / lost + PARAM_TRANSIT1 = 11, // run=11 -> transit in space + PARAM_TRANSIT2 = 12, // run=12 -> transit in space + PARAM_TRANSIT3 = 13 // run=13 -> transit in space +}; + +enum AutoBasePhase +{ + ABP_WAIT = 1, // expected + ABP_START = 2, // start-up + + ABP_LAND = 3, // landing + ABP_OPENWAIT = 4, // wait before opening + ABP_OPEN = 5, // opens the gate + ABP_OPEN2 = 6, // opens supplements + ABP_LDWAIT = 7, // expected + + ABP_CLOSE2 = 8, // closes supplements + ABP_CLOSE = 9, // closes gate + ABP_TOWAIT = 10, // wait before takeoff + ABP_TAKEOFF = 11, // take-off + + ABP_PORTICO_MOVE = 12, // gate advance + ABP_PORTICO_WAIT1= 13, // gate expected + ABP_PORTICO_DOWN = 14, // gate down + ABP_PORTICO_WAIT2= 15, // gate expected + ABP_PORTICO_OPEN = 16, // gate opens + + ABP_TRANSIT_MOVE = 17, // transit - moving +}; + + + +class CAutoBase : public CAuto +{ +public: + CAutoBase(CInstanceManager* iMan, CObject* object); + ~CAutoBase(); + + void DeleteObject(bool bAll=false); + + void Init(); + void Start(int param); + bool EventProcess(const Event &event); + bool Abort(); + Error RetError(); + + bool CreateInterface(bool bSelect); + +protected: + void UpdateInterface(); + void FreezeCargo(bool bFreeze); + void MoveCargo(); + Error CheckCloseDoor(); + void BeginTransit(); + void EndTransit(); + +protected: + AutoBasePhase m_phase; + bool m_bOpen; + float m_progress; + float m_speed; + float m_lastParticule; + float m_lastMotorParticule; + float m_fogStart; + float m_deepView; + Math::Vector m_pos; + Math::Vector m_posSound; + Math::Vector m_finalPos; + Math::Vector m_lastPos; + int m_param; + int m_soundChannel; + int m_partiChannel[8]; + + char m_bgBack[100]; + char m_bgName[100]; + D3DCOLOR m_bgUp; + D3DCOLOR m_bgDown; + D3DCOLOR m_bgCloudUp; + D3DCOLOR m_bgCloudDown; +}; + diff --git a/src/object/auto/autoconvert.cpp b/src/object/auto/autoconvert.cpp index ffe7d59..b5ad43a 100644 --- a/src/object/auto/autoconvert.cpp +++ b/src/object/auto/autoconvert.cpp @@ -1,527 +1,527 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoconvert.h"
-
-#include "common/iman.h"
-#include "math/geometry.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-
-// Object's constructor.
-
-CAutoConvert::CAutoConvert(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
- m_phase = ACP_STOP;
- m_bResetDelete = false;
- m_soundChannel = -1;
-}
-
-// Object's destructor.
-
-CAutoConvert::~CAutoConvert()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoConvert::DeleteObject(bool bAll)
-{
- CObject* fret;
-
- if ( !bAll )
- {
- fret = SearchStone(OBJECT_STONE);
- if ( fret != 0 )
- {
- fret->DeleteObject(); // destroy the stone
- delete fret;
- }
- }
-
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoConvert::Init()
-{
- m_phase = ACP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoConvert::EventProcess(const Event &event)
-{
- CObject* fret;
- Math::Vector pos, speed;
- Math::Point dim, c, p;
- float angle;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
-
- angle = (Math::Rand()-0.5f)*0.3f;
- m_object->SetAngleY(1, angle);
- m_object->SetAngleY(2, angle);
- m_object->SetAngleY(3, angle+Math::PI);
-
- m_object->SetAngleX(2, -Math::PI*0.35f*(0.8f+Math::Rand()*0.2f));
- m_object->SetAngleX(3, -Math::PI*0.35f*(0.8f+Math::Rand()*0.2f));
- }
- return true;
- }
-
- EventProgress(event.rTime);
-
- if ( m_phase == ACP_STOP ) return true;
-
- if ( m_phase == ACP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- fret = SearchStone(OBJECT_STONE); // Has stone transformed?
- if ( fret == 0 || SearchVehicle() )
- {
- m_phase = ACP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- else
- {
- fret->SetLock(true); // stone usable
-
- SetBusy(true);
- InitProgressTotal(3.0f+10.0f+1.5f);
- UpdateInterface();
-
- m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.0f);
- m_bSoundClose = false;
-
- m_phase = ACP_CLOSE;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
- }
- }
-
- if ( m_phase == ACP_CLOSE )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_progress >= 0.8f && !m_bSoundClose )
- {
- m_bSoundClose = true;
- m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 0.8f);
- }
- angle = -Math::PI*0.35f*(1.0f-Math::Bounce(m_progress, 0.85f, 0.05f));
- m_object->SetAngleX(2, angle);
- m_object->SetAngleX(3, angle);
- }
- else
- {
- m_object->SetAngleX(2, 0.0f);
- m_object->SetAngleX(3, 0.0f);
-
- m_soundChannel = m_sound->Play(SOUND_CONVERT, m_object->RetPosition(0), 0.0f, 0.25f, true);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 0.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.00f, 4.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 4.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 0.5f, SOPER_STOP);
-
- m_phase = ACP_ROTATE;
- m_progress = 0.0f;
- m_speed = 1.0f/10.0f;
- }
- }
-
- if ( m_phase == ACP_ROTATE )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_progress < 0.5f )
- {
- angle = powf((m_progress*2.0f)*5.0f, 2.0f); // accelerates
- }
- else
- {
- angle = -powf((2.0f-m_progress*2.0f)*5.0f, 2.0f); // slows
- }
- m_object->SetAngleY(1, angle);
- m_object->SetAngleY(2, angle);
- m_object->SetAngleY(3, angle+Math::PI);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- c.x = pos.x;
- c.y = pos.z;
- p.x = c.x;
- p.y = c.y+6.0f;
- p = Math::RotatePoint(c, Math::Rand()*Math::PI*2.0f, p);
- pos.x = p.x;
- pos.z = p.y;
- pos.y += 1.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*2.0f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- m_object->SetAngleY(1, 0.0f);
- m_object->SetAngleY(2, 0.0f);
- m_object->SetAngleY(3, Math::PI);
-
- fret = SearchStone(OBJECT_STONE);
- if ( fret != 0 )
- {
- m_bResetDelete = ( fret->RetResetCap() != RESET_NONE );
- fret->DeleteObject(); // destroy the stone
- delete fret;
- }
-
- CreateMetal(); // Create the metal
- m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.5f);
-
- m_phase = ACP_OPEN;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
-
- if ( m_phase == ACP_OPEN )
- {
- if ( m_progress < 1.0f )
- {
- angle = -Math::PI*0.35f*Math::Bounce(m_progress, 0.7f, 0.2f);
- m_object->SetAngleX(2, angle);
- m_object->SetAngleX(3, angle);
-
- if ( m_progress < 0.9f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*6.0f;
- pos.z += (Math::Rand()-0.5f)*6.0f;
- pos.y += Math::Rand()*4.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*4.0f+3.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- m_soundChannel = -1;
- m_object->SetAngleX(2, -Math::PI*0.35f);
- m_object->SetAngleX(3, -Math::PI*0.35f);
-
- SetBusy(false);
- UpdateInterface();
-
- m_phase = ACP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- return true;
-}
-
-// Returns an error due the state of the automation.
-
-Error CAutoConvert::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- if ( m_phase == ACP_WAIT ) return ERR_CONVERT_EMPTY;
- return ERR_OK;
-}
-
-// Cancels the current transformation.
-
-bool CAutoConvert::Abort()
-{
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- m_object->SetAngleY(1, 0.0f);
- m_object->SetAngleY(2, 0.0f);
- m_object->SetAngleY(3, Math::PI);
- m_object->SetAngleX(2, -Math::PI*0.35f);
- m_object->SetAngleX(3, -Math::PI*0.35f);
-
- m_phase = ACP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- SetBusy(false);
- UpdateInterface();
-
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoConvert::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 103, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoConvert::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ACP_STOP ||
- m_phase == ACP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoConvert::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoConvertPhase)OpInt(line, "aPhase", ACP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- return true;
-}
-
-
-// Searches for the object before or during processing.
-
-CObject* CAutoConvert::SearchStone(ObjectType type)
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType oType;
- float dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( oType != type ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, cPos);
-
- if ( dist <= 5.0f ) return pObj;
- }
-
- return 0;
-}
-
-// Search if a vehicle is too close.
-
-bool CAutoConvert::SearchVehicle()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType type;
- float oRadius, dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_HUMAN &&
- type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEtg &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr &&
- type != OBJECT_METAL &&
- type != OBJECT_URANIUM &&
- type != OBJECT_POWER &&
- type != OBJECT_ATOMIC &&
- type != OBJECT_BULLET &&
- type != OBJECT_BBOX &&
- type != OBJECT_TNT &&
- type != OBJECT_MOTHER &&
- type != OBJECT_ANT &&
- type != OBJECT_SPIDER &&
- type != OBJECT_BEE &&
- type != OBJECT_WORM ) continue;
-
- if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue;
- dist = Math::Distance(oPos, cPos)-oRadius;
-
- if ( dist < 8.0f ) return true;
- }
-
- return false;
-}
-
-// Creates an object metal.
-
-void CAutoConvert::CreateMetal()
-{
- Math::Vector pos;
- float angle;
- CObject* fret;
-
- pos = m_object->RetPosition(0);
- angle = m_object->RetAngleY(0);
-
- fret = new CObject(m_iMan);
- if ( !fret->CreateResource(pos, angle, OBJECT_METAL) )
- {
- delete fret;
- m_displayText->DisplayError(ERR_TOOMANY, m_object);
- return;
- }
-
- if ( m_bResetDelete )
- {
- fret->SetResetCap(RESET_DELETE);
- }
-
- m_displayText->DisplayError(INFO_CONVERT, m_object);
-}
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autoconvert.h" + +#include "common/iman.h" +#include "math/geometry.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + + +// Object's constructor. + +CAutoConvert::CAutoConvert(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); + m_phase = ACP_STOP; + m_bResetDelete = false; + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoConvert::~CAutoConvert() +{ +} + + +// Destroys the object. + +void CAutoConvert::DeleteObject(bool bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchStone(OBJECT_STONE); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroy the stone + delete fret; + } + } + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoConvert::Init() +{ + m_phase = ACP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoConvert::EventProcess(const Event &event) +{ + CObject* fret; + Math::Vector pos, speed; + Math::Point dim, c, p; + float angle; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + angle = (Math::Rand()-0.5f)*0.3f; + m_object->SetAngleY(1, angle); + m_object->SetAngleY(2, angle); + m_object->SetAngleY(3, angle+Math::PI); + + m_object->SetAngleX(2, -Math::PI*0.35f*(0.8f+Math::Rand()*0.2f)); + m_object->SetAngleX(3, -Math::PI*0.35f*(0.8f+Math::Rand()*0.2f)); + } + return true; + } + + EventProgress(event.rTime); + + if ( m_phase == ACP_STOP ) return true; + + if ( m_phase == ACP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + fret = SearchStone(OBJECT_STONE); // Has stone transformed? + if ( fret == 0 || SearchVehicle() ) + { + m_phase = ACP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else + { + fret->SetLock(true); // stone usable + + SetBusy(true); + InitProgressTotal(3.0f+10.0f+1.5f); + UpdateInterface(); + + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.0f); + m_bSoundClose = false; + + m_phase = ACP_CLOSE; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + } + + if ( m_phase == ACP_CLOSE ) + { + if ( m_progress < 1.0f ) + { + if ( m_progress >= 0.8f && !m_bSoundClose ) + { + m_bSoundClose = true; + m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 0.8f); + } + angle = -Math::PI*0.35f*(1.0f-Math::Bounce(m_progress, 0.85f, 0.05f)); + m_object->SetAngleX(2, angle); + m_object->SetAngleX(3, angle); + } + else + { + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(3, 0.0f); + + m_soundChannel = m_sound->Play(SOUND_CONVERT, m_object->RetPosition(0), 0.0f, 0.25f, true); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.00f, 4.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 4.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 0.5f, SOPER_STOP); + + m_phase = ACP_ROTATE; + m_progress = 0.0f; + m_speed = 1.0f/10.0f; + } + } + + if ( m_phase == ACP_ROTATE ) + { + if ( m_progress < 1.0f ) + { + if ( m_progress < 0.5f ) + { + angle = powf((m_progress*2.0f)*5.0f, 2.0f); // accelerates + } + else + { + angle = -powf((2.0f-m_progress*2.0f)*5.0f, 2.0f); // slows + } + m_object->SetAngleY(1, angle); + m_object->SetAngleY(2, angle); + m_object->SetAngleY(3, angle+Math::PI); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + c.x = pos.x; + c.y = pos.z; + p.x = c.x; + p.y = c.y+6.0f; + p = Math::RotatePoint(c, Math::Rand()*Math::PI*2.0f, p); + pos.x = p.x; + pos.z = p.y; + pos.y += 1.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*2.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_object->SetAngleY(1, 0.0f); + m_object->SetAngleY(2, 0.0f); + m_object->SetAngleY(3, Math::PI); + + fret = SearchStone(OBJECT_STONE); + if ( fret != 0 ) + { + m_bResetDelete = ( fret->RetResetCap() != RESET_NONE ); + fret->DeleteObject(); // destroy the stone + delete fret; + } + + CreateMetal(); // Create the metal + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.5f); + + m_phase = ACP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ACP_OPEN ) + { + if ( m_progress < 1.0f ) + { + angle = -Math::PI*0.35f*Math::Bounce(m_progress, 0.7f, 0.2f); + m_object->SetAngleX(2, angle); + m_object->SetAngleX(3, angle); + + if ( m_progress < 0.9f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*6.0f; + pos.z += (Math::Rand()-0.5f)*6.0f; + pos.y += Math::Rand()*4.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*4.0f+3.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_soundChannel = -1; + m_object->SetAngleX(2, -Math::PI*0.35f); + m_object->SetAngleX(3, -Math::PI*0.35f); + + SetBusy(false); + UpdateInterface(); + + m_phase = ACP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return true; +} + +// Returns an error due the state of the automation. + +Error CAutoConvert::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + if ( m_phase == ACP_WAIT ) return ERR_CONVERT_EMPTY; + return ERR_OK; +} + +// Cancels the current transformation. + +bool CAutoConvert::Abort() +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_object->SetAngleY(1, 0.0f); + m_object->SetAngleY(2, 0.0f); + m_object->SetAngleY(3, Math::PI); + m_object->SetAngleX(2, -Math::PI*0.35f); + m_object->SetAngleX(3, -Math::PI*0.35f); + + m_phase = ACP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + SetBusy(false); + UpdateInterface(); + + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoConvert::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 103, EVENT_OBJECT_TYPE); + + return true; +} + + +// Saves all parameters of the controller. + +bool CAutoConvert::Write(char *line) +{ + char name[100]; + + if ( m_phase == ACP_STOP || + m_phase == ACP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoConvert::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoConvertPhase)OpInt(line, "aPhase", ACP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + +// Searches for the object before or during processing. + +CObject* CAutoConvert::SearchStone(ObjectType type) +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( oType != type ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, cPos); + + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + +// Search if a vehicle is too close. + +bool CAutoConvert::SearchVehicle() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_METAL && + type != OBJECT_URANIUM && + type != OBJECT_POWER && + type != OBJECT_ATOMIC && + type != OBJECT_BULLET && + type != OBJECT_BBOX && + type != OBJECT_TNT && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Math::Distance(oPos, cPos)-oRadius; + + if ( dist < 8.0f ) return true; + } + + return false; +} + +// Creates an object metal. + +void CAutoConvert::CreateMetal() +{ + Math::Vector pos; + float angle; + CObject* fret; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngleY(0); + + fret = new CObject(m_iMan); + if ( !fret->CreateResource(pos, angle, OBJECT_METAL) ) + { + delete fret; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + + if ( m_bResetDelete ) + { + fret->SetResetCap(RESET_DELETE); + } + + m_displayText->DisplayError(INFO_CONVERT, m_object); +} + diff --git a/src/object/auto/autoconvert.h b/src/object/auto/autoconvert.h index b907c3a..c2042cf 100644 --- a/src/object/auto/autoconvert.h +++ b/src/object/auto/autoconvert.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/.
-
-// autoconvert.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoConvertPhase
-{
- ACP_STOP = 1,
- ACP_WAIT = 2,
- ACP_CLOSE = 3, // close the cover
- ACP_ROTATE = 4, // turn the cover
- ACP_OPEN = 5, // opens the cover
-};
-
-
-
-class CAutoConvert : public CAuto
-{
-public:
- CAutoConvert(CInstanceManager* iMan, CObject* object);
- ~CAutoConvert();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
- bool Abort();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- CObject* SearchStone(ObjectType type);
- bool SearchVehicle();
- void CreateMetal();
-
-protected:
- AutoConvertPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- bool m_bResetDelete;
- bool m_bSoundClose;
- int m_soundChannel;
-};
-
+// * 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/. + +// autoconvert.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoConvertPhase +{ + ACP_STOP = 1, + ACP_WAIT = 2, + ACP_CLOSE = 3, // close the cover + ACP_ROTATE = 4, // turn the cover + ACP_OPEN = 5, // opens the cover +}; + + + +class CAutoConvert : public CAuto +{ +public: + CAutoConvert(CInstanceManager* iMan, CObject* object); + ~CAutoConvert(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + bool Abort(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + CObject* SearchStone(ObjectType type); + bool SearchVehicle(); + void CreateMetal(); + +protected: + AutoConvertPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + bool m_bResetDelete; + bool m_bSoundClose; + int m_soundChannel; +}; + diff --git a/src/object/auto/autoderrick.cpp b/src/object/auto/autoderrick.cpp index fa7cff9..3f1cda5 100644 --- a/src/object/auto/autoderrick.cpp +++ b/src/object/auto/autoderrick.cpp @@ -1,589 +1,589 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoderrick.h"
-
-#include "common/iman.h"
-#include "old/terrain.h"
-#include "math/geometry.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-
-const float DERRICK_DELAY = 10.0f; // duration of the extraction
-const float DERRICK_DELAYu = 30.0f; // same, but for uranium
-
-
-
-
-// Object's constructor.
-
-CAutoDerrick::CAutoDerrick(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
- m_phase = ADP_WAIT; // paused until the first Init ()
- m_soundChannel = -1;
-}
-
-// Object's destructor.
-
-CAutoDerrick::~CAutoDerrick()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoDerrick::DeleteObject(bool bAll)
-{
- CObject* fret;
-
- if ( !bAll )
- {
- fret = SearchFret();
- if ( fret != 0 && fret->RetLock() )
- {
- fret->DeleteObject();
- delete fret;
- }
- }
-
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoDerrick::Init()
-{
- Math::Matrix* mat;
- Math::Vector pos;
- TerrainRes res;
-
- pos = m_object->RetPosition(0);
- res = m_terrain->RetResource(pos);
-
- if ( res == TR_STONE ||
- res == TR_URANIUM ||
- res == TR_KEYa ||
- res == TR_KEYb ||
- res == TR_KEYc ||
- res == TR_KEYd )
- {
- m_type = OBJECT_FRET;
- if ( res == TR_STONE ) m_type = OBJECT_STONE;
- if ( res == TR_URANIUM ) m_type = OBJECT_URANIUM;
- if ( res == TR_KEYa ) m_type = OBJECT_KEYa;
- if ( res == TR_KEYb ) m_type = OBJECT_KEYb;
- if ( res == TR_KEYc ) m_type = OBJECT_KEYc;
- if ( res == TR_KEYd ) m_type = OBJECT_KEYd;
-
- m_phase = ADP_EXCAVATE;
- m_progress = 0.0f;
- m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY);
- }
- else
- {
- m_phase = ADP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f;
- }
-
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
- m_lastTrack = 0.0f;
-
- pos = Math::Vector(7.0f, 0.0f, 0.0f);
- mat = m_object->RetWorldMatrix(0);
- pos = Math::Transform(*mat, pos);
- m_terrain->MoveOnFloor(pos);
- m_fretPos = pos;
-}
-
-
-// Management of an event.
-
-bool CAutoDerrick::EventProcess(const Event &event)
-{
- CObject* fret;
- Math::Vector pos, speed;
- Math::Point dim;
- float angle, duration, factor;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
- if ( m_phase == ADP_WAIT ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
-
- pos.x = 0.0f;
- pos.z = 0.0f;
- pos.y = -2.0f*Math::Rand();
- m_object->SetPosition(1, pos); // up / down the drill
-
- m_object->SetAngleY(1, Math::Rand()*0.5f); // rotates the drill
- }
- return true;
- }
-
- if ( m_phase == ADP_EXCAVATE )
- {
- if ( m_soundChannel == -1 )
- {
- if ( m_type == OBJECT_URANIUM )
- {
- factor = DERRICK_DELAYu/DERRICK_DELAY;
- }
- else
- {
- factor = 1.0f;
- }
- m_soundChannel = m_sound->Play(SOUND_DERRICK, m_object->RetPosition(0), 1.0f, 0.5f, true);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f*factor, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.3f, 6.0f*factor, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 1.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f, SOPER_STOP);
- }
-
- if ( m_progress >= 6.0f/16.0f && // penetrates into the ground?
- m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- 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 >= 6.0f/16.0f && // penetrates into the ground?
- m_lastTrack+m_engine->ParticuleAdapt(0.5f) <= m_time )
- {
- m_lastTrack = m_time;
-
- pos = m_object->RetPosition(0);
- speed.x = (Math::Rand()-0.5f)*12.0f;
- speed.z = (Math::Rand()-0.5f)*12.0f;
- speed.y = Math::Rand()*10.0f+10.0f;
- dim.x = 0.6f;
- dim.y = dim.x;
- pos.y += dim.y;
- duration = Math::Rand()*2.0f+2.0f;
- m_particule->CreateTrack(pos, speed, dim, PARTITRACK5,
- duration, Math::Rand()*10.0f+15.0f,
- duration*0.2f, 1.0f);
- }
-
- if ( m_progress < 1.0f )
- {
- pos.x = 0.0f;
- pos.z = 0.0f;
- pos.y = -m_progress*16.0f;
- m_object->SetPosition(1, pos); // down the drill
-
- angle = m_object->RetAngleY(1);
- angle += event.rTime*8.0f;
- m_object->SetAngleY(1, angle); // rotates the drill
- }
- else
- {
- m_phase = ADP_ASCEND;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- }
- }
-
- if ( m_phase == ADP_ASCEND )
- {
- if ( m_progress <= 7.0f/16.0f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time )
- {
- m_lastParticule = m_time;
-
- 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 <= 4.0f/16.0f &&
- m_lastTrack+m_engine->ParticuleAdapt(1.0f) <= m_time )
- {
- m_lastTrack = m_time;
-
- pos = m_object->RetPosition(0);
- speed.x = (Math::Rand()-0.5f)*12.0f;
- speed.z = (Math::Rand()-0.5f)*12.0f;
- speed.y = Math::Rand()*10.0f+10.0f;
- dim.x = 0.6f;
- dim.y = dim.x;
- pos.y += dim.y;
- duration = Math::Rand()*2.0f+2.0f;
- m_particule->CreateTrack(pos, speed, dim, PARTITRACK5,
- duration, Math::Rand()*10.0f+15.0f,
- duration*0.2f, 1.0f);
- }
-
- if ( m_progress < 1.0f )
- {
- pos.x = 0.0f;
- pos.z = 0.0f;
- pos.y = -(1.0f-m_progress)*16.0f;
- m_object->SetPosition(1, pos); // back the drill
-
- angle = m_object->RetAngleY(1);
- angle -= event.rTime*2.0f;
- m_object->SetAngleY(1, angle); // rotates the drill
- }
- else
- {
- m_soundChannel = -1;
- m_bSoundFall = false;
-
- m_phase = ADP_EXPORT;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- }
- }
-
- if ( m_phase == ADP_ISFREE )
- {
- if ( m_progress >= 1.0f )
- {
- m_bSoundFall = false;
-
- m_phase = ADP_EXPORT;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- }
- }
-
- if ( m_phase == ADP_EXPORT )
- {
- if ( m_progress == 0.0f )
- {
- if ( SearchFree(m_fretPos) )
- {
- angle = m_object->RetAngleY(0);
- CreateFret(m_fretPos, angle, m_type, 16.0f);
- }
- else
- {
- m_phase = ADP_ISFREE;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- return true;
- }
- }
-
- fret = SearchFret();
-
- if ( fret != 0 &&
- m_progress <= 0.5f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time )
- {
- m_lastParticule = m_time;
-
- if ( m_progress < 0.3f )
- {
- pos = fret->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*5.0f;
- pos.z += (Math::Rand()-0.5f)*5.0f;
- pos.y += (Math::Rand()-0.5f)*5.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 3.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIFIRE, 1.0f, 0.0f, 0.0f);
- }
- else
- {
- pos = fret->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*5.0f;
- pos.z += (Math::Rand()-0.5f)*5.0f;
- pos.y += Math::Rand()*2.5f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f);
- }
- }
-
- if ( m_progress < 1.0f )
- {
- if ( fret != 0 )
- {
- pos = fret->RetPosition(0);
- pos.y -= event.rTime*20.0f; // grave
- if ( !m_bSoundFall && pos.y < m_fretPos.y )
- {
- m_sound->Play(SOUND_BOUM, m_fretPos);
- m_bSoundFall = true;
- }
- if ( pos.y < m_fretPos.y )
- {
- pos.y = m_fretPos.y;
- fret->SetLock(false); // object usable
- }
- fret->SetPosition(0, pos);
- }
- }
- else
- {
- if ( ExistKey() ) // key already exists?
- {
- m_phase = ADP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/10.0f;
- }
- else
- {
- m_phase = ADP_EXCAVATE;
- m_progress = 0.0f;
- m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY);
- }
- }
- }
-
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoDerrick::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 109, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoDerrick::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ADP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoDerrick::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoDerrickPhase)OpInt(line, "aPhase", ADP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- return true;
-}
-
-
-// Seeks the subject cargo.
-
-CObject* CAutoDerrick::SearchFret()
-{
- CObject* pObj;
- Math::Vector oPos;
- ObjectType type;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type == OBJECT_DERRICK ) continue;
-
- oPos = pObj->RetPosition(0);
-
- if ( oPos.x == m_fretPos.x &&
- oPos.z == m_fretPos.z ) return pObj;
- }
-
- return 0;
-}
-
-// Seeks if a site is free.
-
-bool CAutoDerrick::SearchFree(Math::Vector pos)
-{
- CObject* pObj;
- Math::Vector sPos;
- ObjectType type;
- float sRadius, distance;
- int i, j;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type == OBJECT_DERRICK ) continue;
-
- j = 0;
- while ( pObj->GetCrashSphere(j++, sPos, sRadius) )
- {
- distance = Math::Distance(sPos, pos);
- distance -= sRadius;
- if ( distance < 2.0f ) return false; // location occupied
- }
- }
-
- return true; // location free
-}
-
-// Create a transportable object.
-
-void CAutoDerrick::CreateFret(Math::Vector pos, float angle, ObjectType type,
- float height)
-{
- CObject* fret;
-
- fret = new CObject(m_iMan);
- if ( !fret->CreateResource(pos, angle, type) )
- {
- delete fret;
- m_displayText->DisplayError(ERR_TOOMANY, m_object);
- return;
- }
- fret->SetLock(true); // object not yet usable
-
- if ( m_object->RetResetCap() == RESET_MOVE )
- {
- fret->SetResetCap(RESET_DELETE);
- }
-
- pos = fret->RetPosition(0);
- pos.y += height;
- fret->SetPosition(0, pos);
-}
-
-// Look if there is already a key.
-
-bool CAutoDerrick::ExistKey()
-{
- CObject* pObj;
- ObjectType type;
- int i;
-
- if ( m_type != OBJECT_KEYa &&
- m_type != OBJECT_KEYb &&
- m_type != OBJECT_KEYc &&
- m_type != OBJECT_KEYd ) return false;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type == m_type ) return true;
- }
-
- return false;
-}
-
-
-// Returns an error due the state of the automaton.
-
-Error CAutoDerrick::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- if ( m_phase == ADP_WAIT ) return ERR_DERRICK_NULL;
- return ERR_OK;
-}
-
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autoderrick.h" + +#include "common/iman.h" +#include "old/terrain.h" +#include "math/geometry.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + + +const float DERRICK_DELAY = 10.0f; // duration of the extraction +const float DERRICK_DELAYu = 30.0f; // same, but for uranium + + + + +// Object's constructor. + +CAutoDerrick::CAutoDerrick(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); + m_phase = ADP_WAIT; // paused until the first Init () + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoDerrick::~CAutoDerrick() +{ +} + + +// Destroys the object. + +void CAutoDerrick::DeleteObject(bool bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchFret(); + if ( fret != 0 && fret->RetLock() ) + { + fret->DeleteObject(); + delete fret; + } + } + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoDerrick::Init() +{ + Math::Matrix* mat; + Math::Vector pos; + TerrainRes res; + + pos = m_object->RetPosition(0); + res = m_terrain->RetResource(pos); + + if ( res == TR_STONE || + res == TR_URANIUM || + res == TR_KEYa || + res == TR_KEYb || + res == TR_KEYc || + res == TR_KEYd ) + { + m_type = OBJECT_FRET; + if ( res == TR_STONE ) m_type = OBJECT_STONE; + if ( res == TR_URANIUM ) m_type = OBJECT_URANIUM; + if ( res == TR_KEYa ) m_type = OBJECT_KEYa; + if ( res == TR_KEYb ) m_type = OBJECT_KEYb; + if ( res == TR_KEYc ) m_type = OBJECT_KEYc; + if ( res == TR_KEYd ) m_type = OBJECT_KEYd; + + m_phase = ADP_EXCAVATE; + m_progress = 0.0f; + m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY); + } + else + { + m_phase = ADP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f; + } + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + m_lastTrack = 0.0f; + + pos = Math::Vector(7.0f, 0.0f, 0.0f); + mat = m_object->RetWorldMatrix(0); + pos = Math::Transform(*mat, pos); + m_terrain->MoveOnFloor(pos); + m_fretPos = pos; +} + + +// Management of an event. + +bool CAutoDerrick::EventProcess(const Event &event) +{ + CObject* fret; + Math::Vector pos, speed; + Math::Point dim; + float angle, duration, factor; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + if ( m_phase == ADP_WAIT ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + pos.x = 0.0f; + pos.z = 0.0f; + pos.y = -2.0f*Math::Rand(); + m_object->SetPosition(1, pos); // up / down the drill + + m_object->SetAngleY(1, Math::Rand()*0.5f); // rotates the drill + } + return true; + } + + if ( m_phase == ADP_EXCAVATE ) + { + if ( m_soundChannel == -1 ) + { + if ( m_type == OBJECT_URANIUM ) + { + factor = DERRICK_DELAYu/DERRICK_DELAY; + } + else + { + factor = 1.0f; + } + m_soundChannel = m_sound->Play(SOUND_DERRICK, m_object->RetPosition(0), 1.0f, 0.5f, true); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f*factor, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.3f, 6.0f*factor, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f, SOPER_STOP); + } + + if ( m_progress >= 6.0f/16.0f && // penetrates into the ground? + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + 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 >= 6.0f/16.0f && // penetrates into the ground? + m_lastTrack+m_engine->ParticuleAdapt(0.5f) <= m_time ) + { + m_lastTrack = m_time; + + pos = m_object->RetPosition(0); + speed.x = (Math::Rand()-0.5f)*12.0f; + speed.z = (Math::Rand()-0.5f)*12.0f; + speed.y = Math::Rand()*10.0f+10.0f; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Math::Rand()*2.0f+2.0f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, + duration, Math::Rand()*10.0f+15.0f, + duration*0.2f, 1.0f); + } + + if ( m_progress < 1.0f ) + { + pos.x = 0.0f; + pos.z = 0.0f; + pos.y = -m_progress*16.0f; + m_object->SetPosition(1, pos); // down the drill + + angle = m_object->RetAngleY(1); + angle += event.rTime*8.0f; + m_object->SetAngleY(1, angle); // rotates the drill + } + else + { + m_phase = ADP_ASCEND; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == ADP_ASCEND ) + { + if ( m_progress <= 7.0f/16.0f && + m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + 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 <= 4.0f/16.0f && + m_lastTrack+m_engine->ParticuleAdapt(1.0f) <= m_time ) + { + m_lastTrack = m_time; + + pos = m_object->RetPosition(0); + speed.x = (Math::Rand()-0.5f)*12.0f; + speed.z = (Math::Rand()-0.5f)*12.0f; + speed.y = Math::Rand()*10.0f+10.0f; + dim.x = 0.6f; + dim.y = dim.x; + pos.y += dim.y; + duration = Math::Rand()*2.0f+2.0f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, + duration, Math::Rand()*10.0f+15.0f, + duration*0.2f, 1.0f); + } + + if ( m_progress < 1.0f ) + { + pos.x = 0.0f; + pos.z = 0.0f; + pos.y = -(1.0f-m_progress)*16.0f; + m_object->SetPosition(1, pos); // back the drill + + angle = m_object->RetAngleY(1); + angle -= event.rTime*2.0f; + m_object->SetAngleY(1, angle); // rotates the drill + } + else + { + m_soundChannel = -1; + m_bSoundFall = false; + + m_phase = ADP_EXPORT; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == ADP_ISFREE ) + { + if ( m_progress >= 1.0f ) + { + m_bSoundFall = false; + + m_phase = ADP_EXPORT; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == ADP_EXPORT ) + { + if ( m_progress == 0.0f ) + { + if ( SearchFree(m_fretPos) ) + { + angle = m_object->RetAngleY(0); + CreateFret(m_fretPos, angle, m_type, 16.0f); + } + else + { + m_phase = ADP_ISFREE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + return true; + } + } + + fret = SearchFret(); + + if ( fret != 0 && + m_progress <= 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + if ( m_progress < 0.3f ) + { + pos = fret->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*5.0f; + pos.z += (Math::Rand()-0.5f)*5.0f; + pos.y += (Math::Rand()-0.5f)*5.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 3.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIRE, 1.0f, 0.0f, 0.0f); + } + else + { + pos = fret->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*5.0f; + pos.z += (Math::Rand()-0.5f)*5.0f; + pos.y += Math::Rand()*2.5f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + } + } + + if ( m_progress < 1.0f ) + { + if ( fret != 0 ) + { + pos = fret->RetPosition(0); + pos.y -= event.rTime*20.0f; // grave + if ( !m_bSoundFall && pos.y < m_fretPos.y ) + { + m_sound->Play(SOUND_BOUM, m_fretPos); + m_bSoundFall = true; + } + if ( pos.y < m_fretPos.y ) + { + pos.y = m_fretPos.y; + fret->SetLock(false); // object usable + } + fret->SetPosition(0, pos); + } + } + else + { + if ( ExistKey() ) // key already exists? + { + m_phase = ADP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/10.0f; + } + else + { + m_phase = ADP_EXCAVATE; + m_progress = 0.0f; + m_speed = 1.0f/(m_type==OBJECT_URANIUM?DERRICK_DELAYu:DERRICK_DELAY); + } + } + } + + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoDerrick::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 109, EVENT_OBJECT_TYPE); + + return true; +} + + +// Saves all parameters of the controller. + +bool CAutoDerrick::Write(char *line) +{ + char name[100]; + + if ( m_phase == ADP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoDerrick::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoDerrickPhase)OpInt(line, "aPhase", ADP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + +// Seeks the subject cargo. + +CObject* CAutoDerrick::SearchFret() +{ + CObject* pObj; + Math::Vector oPos; + ObjectType type; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_DERRICK ) continue; + + oPos = pObj->RetPosition(0); + + if ( oPos.x == m_fretPos.x && + oPos.z == m_fretPos.z ) return pObj; + } + + return 0; +} + +// Seeks if a site is free. + +bool CAutoDerrick::SearchFree(Math::Vector pos) +{ + CObject* pObj; + Math::Vector sPos; + ObjectType type; + float sRadius, distance; + int i, j; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_DERRICK ) continue; + + j = 0; + while ( pObj->GetCrashSphere(j++, sPos, sRadius) ) + { + distance = Math::Distance(sPos, pos); + distance -= sRadius; + if ( distance < 2.0f ) return false; // location occupied + } + } + + return true; // location free +} + +// Create a transportable object. + +void CAutoDerrick::CreateFret(Math::Vector pos, float angle, ObjectType type, + float height) +{ + CObject* fret; + + fret = new CObject(m_iMan); + if ( !fret->CreateResource(pos, angle, type) ) + { + delete fret; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + fret->SetLock(true); // object not yet usable + + if ( m_object->RetResetCap() == RESET_MOVE ) + { + fret->SetResetCap(RESET_DELETE); + } + + pos = fret->RetPosition(0); + pos.y += height; + fret->SetPosition(0, pos); +} + +// Look if there is already a key. + +bool CAutoDerrick::ExistKey() +{ + CObject* pObj; + ObjectType type; + int i; + + if ( m_type != OBJECT_KEYa && + m_type != OBJECT_KEYb && + m_type != OBJECT_KEYc && + m_type != OBJECT_KEYd ) return false; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == m_type ) return true; + } + + return false; +} + + +// Returns an error due the state of the automaton. + +Error CAutoDerrick::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + if ( m_phase == ADP_WAIT ) return ERR_DERRICK_NULL; + return ERR_OK; +} + + diff --git a/src/object/auto/autoderrick.h b/src/object/auto/autoderrick.h index e211c0f..61a1ff1 100644 --- a/src/object/auto/autoderrick.h +++ b/src/object/auto/autoderrick.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/.
-
-// autoderrick.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoDerrickPhase
-{
- ADP_WAIT = 1,
- ADP_EXCAVATE = 2, // down the drill
- ADP_ASCEND = 3, // up the drill
- ADP_EXPORT = 4, // exports matter
- ADP_ISFREE = 5, // expected material loss
-};
-
-
-
-class CAutoDerrick : public CAuto
-{
-public:
- CAutoDerrick(CInstanceManager* iMan, CObject* object);
- ~CAutoDerrick();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- CObject* SearchFret();
- bool SearchFree(Math::Vector pos);
- void CreateFret(Math::Vector pos, float angle, ObjectType type, float height);
- bool ExistKey();
-
-protected:
- AutoDerrickPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- float m_lastTrack;
- Math::Vector m_fretPos;
- int m_soundChannel;
- bool m_bSoundFall;
-};
-
+// * 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/. + +// autoderrick.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoDerrickPhase +{ + ADP_WAIT = 1, + ADP_EXCAVATE = 2, // down the drill + ADP_ASCEND = 3, // up the drill + ADP_EXPORT = 4, // exports matter + ADP_ISFREE = 5, // expected material loss +}; + + + +class CAutoDerrick : public CAuto +{ +public: + CAutoDerrick(CInstanceManager* iMan, CObject* object); + ~CAutoDerrick(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + CObject* SearchFret(); + bool SearchFree(Math::Vector pos); + void CreateFret(Math::Vector pos, float angle, ObjectType type, float height); + bool ExistKey(); + +protected: + AutoDerrickPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + float m_lastTrack; + Math::Vector m_fretPos; + int m_soundChannel; + bool m_bSoundFall; +}; + diff --git a/src/object/auto/autodestroyer.cpp b/src/object/auto/autodestroyer.cpp index f1f018c..b40c374 100644 --- a/src/object/auto/autodestroyer.cpp +++ b/src/object/auto/autodestroyer.cpp @@ -1,374 +1,374 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autodestroyer.h"
-
-#include "common/iman.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-
-
-
-
-// Object's constructor.
-
-CAutoDestroyer::CAutoDestroyer(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
- m_phase = ADEP_WAIT; // paused until the first Init ()
-}
-
-// Destructive of the object.
-
-CAutoDestroyer::~CAutoDestroyer()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoDestroyer::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoDestroyer::Init()
-{
- m_phase = ADEP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/0.5f;
-
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoDestroyer::EventProcess(const Event &event)
-{
- CObject* scrap;
- CPyro* pyro;
- Math::Vector pos, speed;
- Math::Point dim;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
- }
- return true;
- }
-
- if ( m_phase == ADEP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- scrap = SearchPlastic();
- if ( scrap == 0 )
- {
- m_phase = ADEP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/0.5f;
- }
- else
- {
- scrap->SetLock(true); // usable waste
-//? scrap->SetTruck(m_object); // usable waste
-
- if ( SearchVehicle() )
- {
- m_phase = ADEP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/0.5f;
- }
- else
- {
- m_sound->Play(SOUND_PSHHH2, m_object->RetPosition(0), 1.0f, 1.0f);
-
- m_phase = ADEP_DOWN;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- m_bExplo = false;
- }
- }
- }
- }
-
- if ( m_phase == ADEP_DOWN )
- {
- if ( m_progress >= 0.3f-0.05f && !m_bExplo )
- {
- scrap = SearchPlastic();
- if ( scrap != 0 )
- {
- pyro = new CPyro(m_iMan);
- pyro->Create(PT_FRAGT, scrap);
- }
- m_bExplo = true;
- }
-
- if ( m_progress < 1.0f )
- {
- pos = Math::Vector(0.0f, -10.0f, 0.0f);
- pos.y = -Math::Bounce(m_progress, 0.3f)*10.0f;
- m_object->SetPosition(1, pos);
- }
- else
- {
- m_object->SetPosition(1, Math::Vector(0.0f, -10.0f, 0.0f));
- m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0));
-
- m_phase = ADEP_REPAIR;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ADEP_REPAIR )
- {
- if ( m_progress < 1.0f )
- {
- }
- else
- {
- m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f);
-
- m_phase = ADEP_UP;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
- }
-
- if ( m_phase == ADEP_UP )
- {
- if ( m_progress < 1.0f )
- {
- pos = Math::Vector(0.0f, -10.0f, 0.0f);
- pos.y = -(1.0f-m_progress)*10.0f;
- m_object->SetPosition(1, pos);
- }
- else
- {
- m_object->SetPosition(1, Math::Vector(0.0f, 0.0f, 0.0f));
-
- m_phase = ADEP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/0.5f;
- }
- }
-
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoDestroyer::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-
-// Seeks plate waste in the destroyer.
-
-CObject* CAutoDestroyer::SearchPlastic()
-{
- CObject* pObj;
- Math::Vector sPos, oPos;
- ObjectType type;
- float dist;
- int i;
-
- sPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_SCRAP4 &&
- type != OBJECT_SCRAP5 ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, sPos);
- if ( dist <= 5.0f ) return pObj;
- }
-
- return 0;
-}
-
-// Seeks if one vehicle is too close.
-
-bool CAutoDestroyer::SearchVehicle()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType type;
- float oRadius, dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_HUMAN &&
- type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEtg &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr &&
- type != OBJECT_MOTHER &&
- type != OBJECT_ANT &&
- type != OBJECT_SPIDER &&
- type != OBJECT_BEE &&
- type != OBJECT_WORM ) continue;
-
- if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue;
- dist = Math::Distance(oPos, cPos)-oRadius;
-
- if ( dist < 20.0f ) return true;
- }
-
- return false;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoDestroyer::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- return ERR_OK;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoDestroyer::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ADEP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoDestroyer::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoDestroyerPhase)OpInt(line, "aPhase", ADEP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autodestroyer.h" + +#include "common/iman.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" + + + + +// Object's constructor. + +CAutoDestroyer::CAutoDestroyer(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); + m_phase = ADEP_WAIT; // paused until the first Init () +} + +// Destructive of the object. + +CAutoDestroyer::~CAutoDestroyer() +{ +} + + +// Destroys the object. + +void CAutoDestroyer::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoDestroyer::Init() +{ + m_phase = ADEP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoDestroyer::EventProcess(const Event &event) +{ + CObject* scrap; + CPyro* pyro; + Math::Vector pos, speed; + Math::Point dim; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + } + return true; + } + + if ( m_phase == ADEP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + scrap = SearchPlastic(); + if ( scrap == 0 ) + { + m_phase = ADEP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + } + else + { + scrap->SetLock(true); // usable waste +//? scrap->SetTruck(m_object); // usable waste + + if ( SearchVehicle() ) + { + m_phase = ADEP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + } + else + { + m_sound->Play(SOUND_PSHHH2, m_object->RetPosition(0), 1.0f, 1.0f); + + m_phase = ADEP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + m_bExplo = false; + } + } + } + } + + if ( m_phase == ADEP_DOWN ) + { + if ( m_progress >= 0.3f-0.05f && !m_bExplo ) + { + scrap = SearchPlastic(); + if ( scrap != 0 ) + { + pyro = new CPyro(m_iMan); + pyro->Create(PT_FRAGT, scrap); + } + m_bExplo = true; + } + + if ( m_progress < 1.0f ) + { + pos = Math::Vector(0.0f, -10.0f, 0.0f); + pos.y = -Math::Bounce(m_progress, 0.3f)*10.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, Math::Vector(0.0f, -10.0f, 0.0f)); + m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); + + m_phase = ADEP_REPAIR; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ADEP_REPAIR ) + { + if ( m_progress < 1.0f ) + { + } + else + { + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + + m_phase = ADEP_UP; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + if ( m_phase == ADEP_UP ) + { + if ( m_progress < 1.0f ) + { + pos = Math::Vector(0.0f, -10.0f, 0.0f); + pos.y = -(1.0f-m_progress)*10.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, Math::Vector(0.0f, 0.0f, 0.0f)); + + m_phase = ADEP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/0.5f; + } + } + + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoDestroyer::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE); + + return true; +} + + +// Seeks plate waste in the destroyer. + +CObject* CAutoDestroyer::SearchPlastic() +{ + CObject* pObj; + Math::Vector sPos, oPos; + ObjectType type; + float dist; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_SCRAP4 && + type != OBJECT_SCRAP5 ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, sPos); + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + +// Seeks if one vehicle is too close. + +bool CAutoDestroyer::SearchVehicle() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Math::Distance(oPos, cPos)-oRadius; + + if ( dist < 20.0f ) return true; + } + + return false; +} + + +// Returns an error due the state of the automation. + +Error CAutoDestroyer::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Saves all parameters of the controller. + +bool CAutoDestroyer::Write(char *line) +{ + char name[100]; + + if ( m_phase == ADEP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoDestroyer::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoDestroyerPhase)OpInt(line, "aPhase", ADEP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autodestroyer.h b/src/object/auto/autodestroyer.h index a233b88..88c93ea 100644 --- a/src/object/auto/autodestroyer.h +++ b/src/object/auto/autodestroyer.h @@ -1,65 +1,65 @@ -// * 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/.
-
-// autodestroyer.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoDestroyerPhase
-{
- ADEP_WAIT = 1, // expected metal
- ADEP_DOWN = 2, // down the cover
- ADEP_REPAIR = 3, // built the vehicle
- ADEP_UP = 4, // up the cover
-};
-
-
-
-class CAutoDestroyer : public CAuto
-{
-public:
- CAutoDestroyer(CInstanceManager* iMan, CObject* object);
- ~CAutoDestroyer();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- CObject* SearchPlastic();
- bool SearchVehicle();
-
-protected:
- AutoDestroyerPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- bool m_bExplo;
-};
-
+// * 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/. + +// autodestroyer.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoDestroyerPhase +{ + ADEP_WAIT = 1, // expected metal + ADEP_DOWN = 2, // down the cover + ADEP_REPAIR = 3, // built the vehicle + ADEP_UP = 4, // up the cover +}; + + + +class CAutoDestroyer : public CAuto +{ +public: + CAutoDestroyer(CInstanceManager* iMan, CObject* object); + ~CAutoDestroyer(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + CObject* SearchPlastic(); + bool SearchVehicle(); + +protected: + AutoDestroyerPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + bool m_bExplo; +}; + diff --git a/src/object/auto/autoegg.cpp b/src/object/auto/autoegg.cpp index 773718c..b1e1c03 100644 --- a/src/object/auto/autoegg.cpp +++ b/src/object/auto/autoegg.cpp @@ -1,359 +1,359 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoegg.h"
-
-#include "math/geometry.h"
-#include "common/iman.h"
-#include "script/cmdtoken.h"
-
-
-
-
-// Object's constructor.
-
-CAutoEgg::CAutoEgg(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- m_type = OBJECT_NULL;
- m_value = 0.0f;
- m_string[0] = 0;
-
- m_param = 0;
- m_phase = AEP_NULL;
- Init();
-}
-
-// Object's destructor.
-
-CAutoEgg::~CAutoEgg()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoEgg::DeleteObject(bool bAll)
-{
- CObject* alien;
-
- CAuto::DeleteObject(bAll);
-
- if ( !bAll )
- {
- alien = SearchAlien();
- if ( alien != 0 )
- {
- // Probably the intended action
- // Original code: ( alien->RetZoom(0) == 1.0f )
- if ( alien->RetZoomY(0) == 1.0f )
- {
- alien->SetLock(false);
- alien->SetActivity(true); // the insect is active
- }
- else
- {
- alien->DeleteObject();
- delete alien;
- }
- }
- }
-}
-
-
-// Initialize the object.
-
-void CAutoEgg::Init()
-{
- CObject* alien;
-
- alien = SearchAlien();
- if ( alien == 0 )
- {
- m_phase = AEP_NULL;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- m_time = 0.0f;
- return;
- }
-
- m_phase = AEP_INCUB;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- m_time = 0.0f;
-
- m_type = alien->RetType();
-
- if ( m_type == OBJECT_ANT ||
- m_type == OBJECT_SPIDER ||
- m_type == OBJECT_BEE )
- {
- alien->SetZoom(0, 0.2f);
- }
- if ( m_type == OBJECT_WORM )
- {
- alien->SetZoom(0, 0.01f); // invisible !
- }
- alien->SetLock(true);
- alien->SetActivity(false);
-}
-
-
-// Gives a value.
-
-bool CAutoEgg::SetType(ObjectType type)
-{
- m_type = type;
- return true;
-}
-
-// Gives a value.
-
-bool CAutoEgg::SetValue(int rank, float value)
-{
- if ( rank != 0 ) return false;
- m_value = value;
- return true;
-}
-
-// Gives the string.
-
-bool CAutoEgg::SetString(char *string)
-{
- strcpy(m_string, string);
- return true;
-}
-
-
-// Start object.
-
-void CAutoEgg::Start(int param)
-{
- if ( m_type == OBJECT_NULL ) return;
- if ( m_value == 0.0f ) return;
-
- m_phase = AEP_DELAY;
- m_progress = 0.0f;
- m_speed = 1.0f/m_value;
-
- m_param = param;
-}
-
-
-// Management of an event.
-
-bool CAutoEgg::EventProcess(const Event &event)
-{
- CObject* alien;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
-
- if ( event.event != EVENT_FRAME ) return true;
- if ( m_phase == AEP_NULL ) return true;
-
- if ( m_phase == AEP_DELAY )
- {
- m_progress += event.rTime*m_speed;
- if ( m_progress < 1.0f ) return true;
-
- alien = new CObject(m_iMan);
- if ( !alien->CreateInsect(m_object->RetPosition(0), m_object->RetAngleY(0), m_type) )
- {
- delete alien;
- m_phase = AEP_DELAY;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- return true;
- }
- alien->SetActivity(false);
- alien->ReadProgram(0, m_string);
- alien->RunProgram(0);
- Init();
- }
-
- alien = SearchAlien();
- if ( alien == 0 ) return true;
- alien->SetActivity(false);
-
- m_progress += event.rTime*m_speed;
-
- if ( m_phase == AEP_ZOOM )
- {
- if ( m_type == OBJECT_ANT ||
- m_type == OBJECT_SPIDER ||
- m_type == OBJECT_BEE )
- {
- alien->SetZoom(0, 0.2f+m_progress*0.8f); // Others push
- }
- }
-
- return true;
-}
-
-// Indicates whether the controller has completed its activity.
-
-Error CAutoEgg::IsEnded()
-{
- CObject* alien;
- CPyro* pyro;
-
- if ( m_phase == AEP_DELAY )
- {
- return ERR_CONTINUE;
- }
-
- alien = SearchAlien();
- if ( alien == 0 ) return ERR_STOP;
-
- if ( m_phase == AEP_INCUB )
- {
- if ( m_progress < 1.0f ) return ERR_CONTINUE;
-
- m_phase = AEP_ZOOM;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- }
-
- if ( m_phase == AEP_ZOOM )
- {
- if ( m_progress < 1.0f ) return ERR_CONTINUE;
-
- pyro = new CPyro(m_iMan);
- pyro->Create(PT_EGG, m_object); // exploding egg
-
- alien->SetZoom(0, 1.0f); // this is a big boy now
-
- m_phase = AEP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
-
- if ( m_phase == AEP_WAIT )
- {
- if ( m_progress < 1.0f ) return ERR_CONTINUE;
-
- alien->SetLock(false);
- alien->SetActivity(true); // the insect is active
- }
-
- return ERR_STOP;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoEgg::RetError()
-{
- return ERR_OK;
-}
-
-
-// Seeking the insect that starts in the egg.
-
-CObject* CAutoEgg::SearchAlien()
-{
- CObject* pObj;
- CObject* pBest;
- Math::Vector cPos, oPos;
- ObjectType type;
- float dist, min;
- int i;
-
- cPos = m_object->RetPosition(0);
- min = 100000.0f;
- pBest = 0;
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj->RetTruck() != 0 ) continue;
-
- type = pObj->RetType();
- if ( type != OBJECT_ANT &&
- type != OBJECT_BEE &&
- type != OBJECT_SPIDER &&
- type != OBJECT_WORM ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::DistanceProjected(oPos, cPos);
- if ( dist < 8.0f && dist < min )
- {
- min = dist;
- pBest = pObj;
- }
- }
- return pBest;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoEgg::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == AEP_NULL ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.5f", m_speed);
- strcat(line, name);
-
- sprintf(name, " aParamType=%s", GetTypeObject(m_type));
- strcat(line, name);
-
- sprintf(name, " aParamValue1=%.2f", m_value);
- strcat(line, name);
-
- sprintf(name, " aParamString=\"%s\"", m_string);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoEgg::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoEggPhase)OpInt(line, "aPhase", AEP_NULL);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
- m_type = OpTypeObject(line, "aParamType", OBJECT_NULL);
- m_value = OpFloat(line, "aParamValue1", 0.0f);
- OpString(line, "aParamString", m_string);
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autoegg.h" + +#include "math/geometry.h" +#include "common/iman.h" +#include "script/cmdtoken.h" + + + + +// Object's constructor. + +CAutoEgg::CAutoEgg(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + m_type = OBJECT_NULL; + m_value = 0.0f; + m_string[0] = 0; + + m_param = 0; + m_phase = AEP_NULL; + Init(); +} + +// Object's destructor. + +CAutoEgg::~CAutoEgg() +{ +} + + +// Destroys the object. + +void CAutoEgg::DeleteObject(bool bAll) +{ + CObject* alien; + + CAuto::DeleteObject(bAll); + + if ( !bAll ) + { + alien = SearchAlien(); + if ( alien != 0 ) + { + // Probably the intended action + // Original code: ( alien->RetZoom(0) == 1.0f ) + if ( alien->RetZoomY(0) == 1.0f ) + { + alien->SetLock(false); + alien->SetActivity(true); // the insect is active + } + else + { + alien->DeleteObject(); + delete alien; + } + } + } +} + + +// Initialize the object. + +void CAutoEgg::Init() +{ + CObject* alien; + + alien = SearchAlien(); + if ( alien == 0 ) + { + m_phase = AEP_NULL; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + m_time = 0.0f; + return; + } + + m_phase = AEP_INCUB; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + m_time = 0.0f; + + m_type = alien->RetType(); + + if ( m_type == OBJECT_ANT || + m_type == OBJECT_SPIDER || + m_type == OBJECT_BEE ) + { + alien->SetZoom(0, 0.2f); + } + if ( m_type == OBJECT_WORM ) + { + alien->SetZoom(0, 0.01f); // invisible ! + } + alien->SetLock(true); + alien->SetActivity(false); +} + + +// Gives a value. + +bool CAutoEgg::SetType(ObjectType type) +{ + m_type = type; + return true; +} + +// Gives a value. + +bool CAutoEgg::SetValue(int rank, float value) +{ + if ( rank != 0 ) return false; + m_value = value; + return true; +} + +// Gives the string. + +bool CAutoEgg::SetString(char *string) +{ + strcpy(m_string, string); + return true; +} + + +// Start object. + +void CAutoEgg::Start(int param) +{ + if ( m_type == OBJECT_NULL ) return; + if ( m_value == 0.0f ) return; + + m_phase = AEP_DELAY; + m_progress = 0.0f; + m_speed = 1.0f/m_value; + + m_param = param; +} + + +// Management of an event. + +bool CAutoEgg::EventProcess(const Event &event) +{ + CObject* alien; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + + if ( event.event != EVENT_FRAME ) return true; + if ( m_phase == AEP_NULL ) return true; + + if ( m_phase == AEP_DELAY ) + { + m_progress += event.rTime*m_speed; + if ( m_progress < 1.0f ) return true; + + alien = new CObject(m_iMan); + if ( !alien->CreateInsect(m_object->RetPosition(0), m_object->RetAngleY(0), m_type) ) + { + delete alien; + m_phase = AEP_DELAY; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + return true; + } + alien->SetActivity(false); + alien->ReadProgram(0, m_string); + alien->RunProgram(0); + Init(); + } + + alien = SearchAlien(); + if ( alien == 0 ) return true; + alien->SetActivity(false); + + m_progress += event.rTime*m_speed; + + if ( m_phase == AEP_ZOOM ) + { + if ( m_type == OBJECT_ANT || + m_type == OBJECT_SPIDER || + m_type == OBJECT_BEE ) + { + alien->SetZoom(0, 0.2f+m_progress*0.8f); // Others push + } + } + + return true; +} + +// Indicates whether the controller has completed its activity. + +Error CAutoEgg::IsEnded() +{ + CObject* alien; + CPyro* pyro; + + if ( m_phase == AEP_DELAY ) + { + return ERR_CONTINUE; + } + + alien = SearchAlien(); + if ( alien == 0 ) return ERR_STOP; + + if ( m_phase == AEP_INCUB ) + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + m_phase = AEP_ZOOM; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + + if ( m_phase == AEP_ZOOM ) + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + pyro = new CPyro(m_iMan); + pyro->Create(PT_EGG, m_object); // exploding egg + + alien->SetZoom(0, 1.0f); // this is a big boy now + + m_phase = AEP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + + if ( m_phase == AEP_WAIT ) + { + if ( m_progress < 1.0f ) return ERR_CONTINUE; + + alien->SetLock(false); + alien->SetActivity(true); // the insect is active + } + + return ERR_STOP; +} + + +// Returns an error due the state of the automation. + +Error CAutoEgg::RetError() +{ + return ERR_OK; +} + + +// Seeking the insect that starts in the egg. + +CObject* CAutoEgg::SearchAlien() +{ + CObject* pObj; + CObject* pBest; + Math::Vector cPos, oPos; + ObjectType type; + float dist, min; + int i; + + cPos = m_object->RetPosition(0); + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetTruck() != 0 ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_ANT && + type != OBJECT_BEE && + type != OBJECT_SPIDER && + type != OBJECT_WORM ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::DistanceProjected(oPos, cPos); + if ( dist < 8.0f && dist < min ) + { + min = dist; + pBest = pObj; + } + } + return pBest; +} + + +// Saves all parameters of the controller. + +bool CAutoEgg::Write(char *line) +{ + char name[100]; + + if ( m_phase == AEP_NULL ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.5f", m_speed); + strcat(line, name); + + sprintf(name, " aParamType=%s", GetTypeObject(m_type)); + strcat(line, name); + + sprintf(name, " aParamValue1=%.2f", m_value); + strcat(line, name); + + sprintf(name, " aParamString=\"%s\"", m_string); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoEgg::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoEggPhase)OpInt(line, "aPhase", AEP_NULL); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_type = OpTypeObject(line, "aParamType", OBJECT_NULL); + m_value = OpFloat(line, "aParamValue1", 0.0f); + OpString(line, "aParamString", m_string); + + return true; +} + diff --git a/src/object/auto/autoegg.h b/src/object/auto/autoegg.h index fcdf760..443dff6 100644 --- a/src/object/auto/autoegg.h +++ b/src/object/auto/autoegg.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/.
-
-// autoegg.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-enum AutoEggPhase
-{
- AEP_NULL = 0,
- AEP_DELAY = 1,
- AEP_INCUB = 3,
- AEP_ZOOM = 4,
- AEP_WAIT = 5,
-};
-
-
-
-class CAutoEgg : public CAuto
-{
-public:
- CAutoEgg(CInstanceManager* iMan, CObject* object);
- ~CAutoEgg();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- void Start(int param);
- bool EventProcess(const Event &event);
- Error IsEnded();
- Error RetError();
-
- bool SetType(ObjectType type);
- bool SetValue(int rank, float value);
- bool SetString(char *string);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- CObject* SearchAlien();
-
-protected:
- ObjectType m_type;
- float m_value;
- char m_string[100];
- int m_param;
- AutoEggPhase m_phase;
- float m_progress;
- float m_speed;
-};
-
+// * 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/. + +// autoegg.h + +#pragma once + + +#include "object/auto/auto.h" + + +enum AutoEggPhase +{ + AEP_NULL = 0, + AEP_DELAY = 1, + AEP_INCUB = 3, + AEP_ZOOM = 4, + AEP_WAIT = 5, +}; + + + +class CAutoEgg : public CAuto +{ +public: + CAutoEgg(CInstanceManager* iMan, CObject* object); + ~CAutoEgg(); + + void DeleteObject(bool bAll=false); + + void Init(); + void Start(int param); + bool EventProcess(const Event &event); + Error IsEnded(); + Error RetError(); + + bool SetType(ObjectType type); + bool SetValue(int rank, float value); + bool SetString(char *string); + + bool Write(char *line); + bool Read(char *line); + +protected: + CObject* SearchAlien(); + +protected: + ObjectType m_type; + float m_value; + char m_string[100]; + int m_param; + AutoEggPhase m_phase; + float m_progress; + float m_speed; +}; + diff --git a/src/object/auto/autoenergy.cpp b/src/object/auto/autoenergy.cpp index 74db234..37c2f29 100644 --- a/src/object/auto/autoenergy.cpp +++ b/src/object/auto/autoenergy.cpp @@ -1,647 +1,647 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoenergy.h"
-
-#include "common/iman.h"
-#include "old/terrain.h"
-#include "math/geometry.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/gauge.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-const float ENERGY_POWER = 0.4f; // Necessary energy for a battery
-const float ENERGY_DELAY = 12.0f; // processing time
-
-
-
-
-// Object's constructor.
-
-CAutoEnergy::CAutoEnergy(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- m_partiSphere = -1;
- Init();
-}
-
-// Object's destructor.
-
-CAutoEnergy::~CAutoEnergy()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoEnergy::DeleteObject(bool bAll)
-{
- CObject* fret;
-
- if ( m_partiSphere != -1 )
- {
- m_particule->DeleteParticule(m_partiSphere);
- m_partiSphere = -1;
- }
-
- if ( !bAll )
- {
- fret = SearchMetal();
- if ( fret != 0 )
- {
- fret->DeleteObject(); // destroys the metal
- delete fret;
- }
-
- fret = SearchPower();
- if ( fret != 0 )
- {
- fret->DeleteObject(); // destroys the cell
- delete fret;
- }
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoEnergy::Init()
-{
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastUpdateTime = 0.0f;
- m_lastParticule = 0.0f;
-
- m_phase = AENP_WAIT; // waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoEnergy::EventProcess(const Event &event)
-{
- CObject* fret;
- Math::Vector pos, ppos, speed;
- Math::Point dim, c, p;
- TerrainRes res;
- float big;
- bool bGO;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
- pos = m_object->RetPosition(0);
- pos.y += 10.0f;
- speed.x = (Math::Rand()-0.5f)*10.0f;
- speed.z = (Math::Rand()-0.5f)*10.0f;
- speed.y = -7.0f;
- dim.x = Math::Rand()*0.5f+0.5f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f);
- }
- }
- return true;
- }
-
- UpdateInterface(event.rTime);
- EventProgress(event.rTime);
-
- big = m_object->RetEnergy();
-
- res = m_terrain->RetResource(m_object->RetPosition(0));
- if ( res == TR_POWER )
- {
- big += event.rTime*0.01f; // recharges the big pile
- }
-
- if ( m_phase == AENP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- bGO = false;
- fret = SearchMetal(); // transform metal?
- if ( fret != 0 )
- {
- if ( fret->RetType() == OBJECT_METAL )
- {
- if ( big > ENERGY_POWER ) bGO = true;
- }
- else
- {
- if ( !SearchVehicle() ) bGO = true;
- }
- }
-
- if ( bGO )
- {
- if ( fret->RetType() == OBJECT_METAL )
- {
- fret->SetLock(true); // usable metal
- CreatePower(); // creates the battery
- }
-
- SetBusy(true);
- InitProgressTotal(ENERGY_DELAY);
- CAuto::UpdateInterface();
-
- pos = m_object->RetPosition(0);
- pos.y += 4.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 3.0f;
- dim.y = dim.x;
- m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE1, ENERGY_DELAY, 0.0f, 0.0f);
-
- m_phase = AENP_CREATE;
- m_progress = 0.0f;
- m_speed = 1.0f/ENERGY_DELAY;
- }
- else
- {
- if ( rand()%3 == 0 && big > 0.01f )
- {
- m_phase = AENP_BLITZ;
- m_progress = 0.0f;
- m_speed = 1.0f/Math::Rand()*1.0f+1.0f;
- }
- else
- {
- m_phase = AENP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
- }
- }
-
- if ( m_phase == AENP_BLITZ )
- {
- if ( m_progress < 1.0f && big > 0.01f )
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
- pos = m_object->RetPosition(0);
- pos.y += 10.0f;
- speed.x = (Math::Rand()-0.5f)*1.0f;
- speed.z = (Math::Rand()-0.5f)*1.0f;
- speed.y = -7.0f;
- dim.x = Math::Rand()*0.5f+0.5f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- m_phase = AENP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == AENP_CREATE )
- {
- if ( m_progress < 1.0f )
- {
- fret = SearchMetal();
- if ( fret != 0 )
- {
- if ( fret->RetType() == OBJECT_METAL )
- {
- big -= event.rTime/ENERGY_DELAY*ENERGY_POWER;
- }
- else
- {
- big += event.rTime/ENERGY_DELAY*0.25f;
- }
- fret->SetZoom(0, 1.0f-m_progress);
- }
-
- fret = SearchPower();
- if ( fret != 0 )
- {
- fret->SetZoom(0, m_progress);
- }
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- c.x = pos.x;
- c.y = pos.z;
- p.x = c.x;
- p.y = c.y+2.0f;
- p = Math::RotatePoint(c, Math::Rand()*Math::PI*2.0f, p);
- pos.x = p.x;
- pos.z = p.y;
- pos.y += 2.5f+Math::Rand()*3.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*2.0f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f);
-
- pos = m_object->RetPosition(0);
- pos.y += 3.0f;
- speed.x = (Math::Rand()-0.5f)*30.0f;
- speed.z = (Math::Rand()-0.5f)*30.0f;
- speed.y = Math::Rand()*20.0f+10.0f;
- dim.x = Math::Rand()*0.4f+0.4f;
- dim.y = dim.x;
- m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, 2.0f, 50.0f, 1.2f, 1.2f);
-
- pos = m_object->RetPosition(0);
- pos.y += 10.0f;
- speed.x = (Math::Rand()-0.5f)*1.5f;
- speed.z = (Math::Rand()-0.5f)*1.5f;
- speed.y = -6.0f;
- dim.x = Math::Rand()*1.0f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f);
-
- m_sound->Play(SOUND_ENERGY, m_object->RetPosition(0),
- 1.0f, 1.0f+Math::Rand()*1.5f);
- }
- }
- else
- {
- fret = SearchMetal();
- if ( fret != 0 )
- {
- m_object->SetPower(0);
- fret->DeleteObject(); // destroys the metal
- delete fret;
- }
-
- fret = SearchPower();
- if ( fret != 0 )
- {
- fret->SetZoom(0, 1.0f);
- fret->SetLock(false); // usable battery
- fret->SetTruck(m_object);
- fret->SetPosition(0, Math::Vector(0.0f, 3.0f, 0.0f));
- m_object->SetPower(fret);
-
- m_displayText->DisplayError(INFO_ENERGY, m_object);
- }
-
- SetBusy(false);
- CAuto::UpdateInterface();
-
- m_phase = AENP_SMOKE;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- }
- }
-
- if ( m_phase == AENP_SMOKE )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- pos.y += 17.0f;
- pos.x += (Math::Rand()-0.5f)*3.0f;
- pos.z += (Math::Rand()-0.5f)*3.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- speed.y = 6.0f+Math::Rand()*6.0f;
- dim.x = Math::Rand()*1.5f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f);
- }
- }
- else
- {
- m_phase = AENP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( big < 0.0f ) big = 0.0f;
- if ( big > 1.0f ) big = 1.0f;
- m_object->SetEnergy(big); // shift the big pile
-
- return true;
-}
-
-
-// Seeking the metal object.
-
-CObject* CAutoEnergy::SearchMetal()
-{
- CObject* pObj;
- ObjectType type;
-
- pObj = m_object->RetPower();
- if ( pObj == 0 ) return 0;
-
- type = pObj->RetType();
- if ( type == OBJECT_METAL ||
- type == OBJECT_SCRAP1 ||
- type == OBJECT_SCRAP2 ||
- type == OBJECT_SCRAP3 ) return pObj;
-
- return 0;
-}
-
-// Search if a vehicle is too close.
-
-bool CAutoEnergy::SearchVehicle()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType type;
- float oRadius, dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_HUMAN &&
- type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEtg &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr &&
- type != OBJECT_MOTHER &&
- type != OBJECT_ANT &&
- type != OBJECT_SPIDER &&
- type != OBJECT_BEE &&
- type != OBJECT_WORM ) continue;
-
- if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue;
- dist = Math::Distance(oPos, cPos)-oRadius;
-
- if ( dist < 10.0f ) return true;
- }
-
- return false;
-}
-
-// Create a cell.
-
-void CAutoEnergy::CreatePower()
-{
- CObject* power;
- Math::Vector pos;
- float angle;
-
- pos = m_object->RetPosition(0);
- angle = m_object->RetAngleY(0);
-
- power = new CObject(m_iMan);
- if ( !power->CreateResource(pos, angle, OBJECT_POWER) )
- {
- delete power;
- m_displayText->DisplayError(ERR_TOOMANY, m_object);
- return;
- }
- power->SetLock(true); // battery not yet usable
-
- pos = power->RetPosition(0);
- pos.y += 3.0f;
- power->SetPosition(0, pos);
-}
-
-// Seeking the battery during manufacture.
-
-CObject* CAutoEnergy::SearchPower()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType type;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( !pObj->RetLock() ) continue;
-
- type = pObj->RetType();
- if ( type != OBJECT_POWER ) continue;
-
- oPos = pObj->RetPosition(0);
- if ( oPos.x == cPos.x &&
- oPos.z == cPos.z )
- {
- return pObj;
- }
- }
-
- return 0;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoEnergy::RetError()
-{
- CObject* pObj;
- ObjectType type;
- TerrainRes res;
-
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- if ( m_phase != AENP_WAIT &&
- m_phase != AENP_BLITZ ) return ERR_OK;
-
- res = m_terrain->RetResource(m_object->RetPosition(0));
- if ( res != TR_POWER ) return ERR_ENERGY_NULL;
-
- if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_ENERGY_LOW;
-
- pObj = m_object->RetPower();
- if ( pObj == 0 ) return ERR_ENERGY_EMPTY;
- type = pObj->RetType();
- if ( type == OBJECT_POWER ) return ERR_OK;
- if ( type != OBJECT_METAL &&
- type != OBJECT_SCRAP1 &&
- type != OBJECT_SCRAP2 &&
- type != OBJECT_SCRAP3 ) return ERR_ENERGY_BAD;
-
- return ERR_OK;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoEnergy::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*14.5f;
- pos.y = oy+sy*0;
- ddim.x = 14.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 108, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-// Updates the state of all buttons on the interface,
-// following the time that elapses ...
-
-void CAutoEnergy::UpdateInterface(float rTime)
-{
- CWindow* pw;
- CGauge* pg;
-
- CAuto::UpdateInterface(rTime);
-
- if ( m_time < m_lastUpdateTime+0.1f ) return;
- m_lastUpdateTime = m_time;
-
- if ( !m_object->RetSelect() ) return;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY);
- if ( pg != 0 )
- {
- pg->SetLevel(m_object->RetEnergy());
- }
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoEnergy::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == AENP_STOP ||
- m_phase == AENP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoEnergy::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoEnergyPhase)OpInt(line, "aPhase", AENP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastUpdateTime = 0.0f;
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autoenergy.h" + +#include "common/iman.h" +#include "old/terrain.h" +#include "math/geometry.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/gauge.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + +const float ENERGY_POWER = 0.4f; // Necessary energy for a battery +const float ENERGY_DELAY = 12.0f; // processing time + + + + +// Object's constructor. + +CAutoEnergy::CAutoEnergy(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + m_partiSphere = -1; + Init(); +} + +// Object's destructor. + +CAutoEnergy::~CAutoEnergy() +{ +} + + +// Destroys the object. + +void CAutoEnergy::DeleteObject(bool bAll) +{ + CObject* fret; + + if ( m_partiSphere != -1 ) + { + m_particule->DeleteParticule(m_partiSphere); + m_partiSphere = -1; + } + + if ( !bAll ) + { + fret = SearchMetal(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the metal + delete fret; + } + + fret = SearchPower(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the cell + delete fret; + } + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoEnergy::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + + m_phase = AENP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoEnergy::EventProcess(const Event &event) +{ + CObject* fret; + Math::Vector pos, ppos, speed; + Math::Point dim, c, p; + TerrainRes res; + float big; + bool bGO; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + pos = m_object->RetPosition(0); + pos.y += 10.0f; + speed.x = (Math::Rand()-0.5f)*10.0f; + speed.z = (Math::Rand()-0.5f)*10.0f; + speed.y = -7.0f; + dim.x = Math::Rand()*0.5f+0.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + } + } + return true; + } + + UpdateInterface(event.rTime); + EventProgress(event.rTime); + + big = m_object->RetEnergy(); + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res == TR_POWER ) + { + big += event.rTime*0.01f; // recharges the big pile + } + + if ( m_phase == AENP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + bGO = false; + fret = SearchMetal(); // transform metal? + if ( fret != 0 ) + { + if ( fret->RetType() == OBJECT_METAL ) + { + if ( big > ENERGY_POWER ) bGO = true; + } + else + { + if ( !SearchVehicle() ) bGO = true; + } + } + + if ( bGO ) + { + if ( fret->RetType() == OBJECT_METAL ) + { + fret->SetLock(true); // usable metal + CreatePower(); // creates the battery + } + + SetBusy(true); + InitProgressTotal(ENERGY_DELAY); + CAuto::UpdateInterface(); + + pos = m_object->RetPosition(0); + pos.y += 4.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 3.0f; + dim.y = dim.x; + m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE1, ENERGY_DELAY, 0.0f, 0.0f); + + m_phase = AENP_CREATE; + m_progress = 0.0f; + m_speed = 1.0f/ENERGY_DELAY; + } + else + { + if ( rand()%3 == 0 && big > 0.01f ) + { + m_phase = AENP_BLITZ; + m_progress = 0.0f; + m_speed = 1.0f/Math::Rand()*1.0f+1.0f; + } + else + { + m_phase = AENP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + } + } + + if ( m_phase == AENP_BLITZ ) + { + if ( m_progress < 1.0f && big > 0.01f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + pos = m_object->RetPosition(0); + pos.y += 10.0f; + speed.x = (Math::Rand()-0.5f)*1.0f; + speed.z = (Math::Rand()-0.5f)*1.0f; + speed.y = -7.0f; + dim.x = Math::Rand()*0.5f+0.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_phase = AENP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AENP_CREATE ) + { + if ( m_progress < 1.0f ) + { + fret = SearchMetal(); + if ( fret != 0 ) + { + if ( fret->RetType() == OBJECT_METAL ) + { + big -= event.rTime/ENERGY_DELAY*ENERGY_POWER; + } + else + { + big += event.rTime/ENERGY_DELAY*0.25f; + } + fret->SetZoom(0, 1.0f-m_progress); + } + + fret = SearchPower(); + if ( fret != 0 ) + { + fret->SetZoom(0, m_progress); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + c.x = pos.x; + c.y = pos.z; + p.x = c.x; + p.y = c.y+2.0f; + p = Math::RotatePoint(c, Math::Rand()*Math::PI*2.0f, p); + pos.x = p.x; + pos.z = p.y; + pos.y += 2.5f+Math::Rand()*3.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*2.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); + + pos = m_object->RetPosition(0); + pos.y += 3.0f; + speed.x = (Math::Rand()-0.5f)*30.0f; + speed.z = (Math::Rand()-0.5f)*30.0f; + speed.y = Math::Rand()*20.0f+10.0f; + dim.x = Math::Rand()*0.4f+0.4f; + dim.y = dim.x; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, 2.0f, 50.0f, 1.2f, 1.2f); + + pos = m_object->RetPosition(0); + pos.y += 10.0f; + speed.x = (Math::Rand()-0.5f)*1.5f; + speed.z = (Math::Rand()-0.5f)*1.5f; + speed.y = -6.0f; + dim.x = Math::Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + + m_sound->Play(SOUND_ENERGY, m_object->RetPosition(0), + 1.0f, 1.0f+Math::Rand()*1.5f); + } + } + else + { + fret = SearchMetal(); + if ( fret != 0 ) + { + m_object->SetPower(0); + fret->DeleteObject(); // destroys the metal + delete fret; + } + + fret = SearchPower(); + if ( fret != 0 ) + { + fret->SetZoom(0, 1.0f); + fret->SetLock(false); // usable battery + fret->SetTruck(m_object); + fret->SetPosition(0, Math::Vector(0.0f, 3.0f, 0.0f)); + m_object->SetPower(fret); + + m_displayText->DisplayError(INFO_ENERGY, m_object); + } + + SetBusy(false); + CAuto::UpdateInterface(); + + m_phase = AENP_SMOKE; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + if ( m_phase == AENP_SMOKE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y += 17.0f; + pos.x += (Math::Rand()-0.5f)*3.0f; + pos.z += (Math::Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 6.0f+Math::Rand()*6.0f; + dim.x = Math::Rand()*1.5f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + } + } + else + { + m_phase = AENP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( big < 0.0f ) big = 0.0f; + if ( big > 1.0f ) big = 1.0f; + m_object->SetEnergy(big); // shift the big pile + + return true; +} + + +// Seeking the metal object. + +CObject* CAutoEnergy::SearchMetal() +{ + CObject* pObj; + ObjectType type; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return 0; + + type = pObj->RetType(); + if ( type == OBJECT_METAL || + type == OBJECT_SCRAP1 || + type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 ) return pObj; + + return 0; +} + +// Search if a vehicle is too close. + +bool CAutoEnergy::SearchVehicle() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Math::Distance(oPos, cPos)-oRadius; + + if ( dist < 10.0f ) return true; + } + + return false; +} + +// Create a cell. + +void CAutoEnergy::CreatePower() +{ + CObject* power; + Math::Vector pos; + float angle; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngleY(0); + + power = new CObject(m_iMan); + if ( !power->CreateResource(pos, angle, OBJECT_POWER) ) + { + delete power; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + power->SetLock(true); // battery not yet usable + + pos = power->RetPosition(0); + pos.y += 3.0f; + power->SetPosition(0, pos); +} + +// Seeking the battery during manufacture. + +CObject* CAutoEnergy::SearchPower() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType type; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_POWER ) continue; + + oPos = pObj->RetPosition(0); + if ( oPos.x == cPos.x && + oPos.z == cPos.z ) + { + return pObj; + } + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoEnergy::RetError() +{ + CObject* pObj; + ObjectType type; + TerrainRes res; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + if ( m_phase != AENP_WAIT && + m_phase != AENP_BLITZ ) return ERR_OK; + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res != TR_POWER ) return ERR_ENERGY_NULL; + + if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_ENERGY_LOW; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return ERR_ENERGY_EMPTY; + type = pObj->RetType(); + if ( type == OBJECT_POWER ) return ERR_OK; + if ( type != OBJECT_METAL && + type != OBJECT_SCRAP1 && + type != OBJECT_SCRAP2 && + type != OBJECT_SCRAP3 ) return ERR_ENERGY_BAD; + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +bool CAutoEnergy::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 108, EVENT_OBJECT_TYPE); + + return true; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoEnergy::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + pg->SetLevel(m_object->RetEnergy()); + } +} + + +// Saves all parameters of the controller. + +bool CAutoEnergy::Write(char *line) +{ + char name[100]; + + if ( m_phase == AENP_STOP || + m_phase == AENP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoEnergy::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoEnergyPhase)OpInt(line, "aPhase", AENP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + + return true; +} diff --git a/src/object/auto/autoenergy.h b/src/object/auto/autoenergy.h index 300ee45..727f2c3 100644 --- a/src/object/auto/autoenergy.h +++ b/src/object/auto/autoenergy.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/.
-
-// autoenergy.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoEnergyPhase
-{
- AENP_STOP = 1,
- AENP_WAIT = 2,
- AENP_BLITZ = 3,
- AENP_CREATE = 4,
- AENP_SMOKE = 5,
-};
-
-
-
-class CAutoEnergy : public CAuto
-{
-public:
- CAutoEnergy(CInstanceManager* iMan, CObject* object);
- ~CAutoEnergy();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- void UpdateInterface(float rTime);
-
- CObject* SearchMetal();
- bool SearchVehicle();
- void CreatePower();
- CObject* SearchPower();
-
-protected:
- AutoEnergyPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastUpdateTime;
- float m_lastParticule;
- int m_partiSphere;
-};
-
+// * 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/. + +// autoenergy.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoEnergyPhase +{ + AENP_STOP = 1, + AENP_WAIT = 2, + AENP_BLITZ = 3, + AENP_CREATE = 4, + AENP_SMOKE = 5, +}; + + + +class CAutoEnergy : public CAuto +{ +public: + CAutoEnergy(CInstanceManager* iMan, CObject* object); + ~CAutoEnergy(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + void UpdateInterface(float rTime); + + CObject* SearchMetal(); + bool SearchVehicle(); + void CreatePower(); + CObject* SearchPower(); + +protected: + AutoEnergyPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + int m_partiSphere; +}; + diff --git a/src/object/auto/autofactory.cpp b/src/object/auto/autofactory.cpp index be5a189..f02195c 100644 --- a/src/object/auto/autofactory.cpp +++ b/src/object/auto/autofactory.cpp @@ -1,941 +1,941 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autofactory.h"
-
-#include "common/global.h"
-#include "common/iman.h"
-#include "math/geometry.h"
-#include "object/robotmain.h"
-#include "physics/physics.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-
-
-// Object's constructor.
-
-CAutoFactory::CAutoFactory(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
- m_type = OBJECT_MOBILEws;
- m_phase = AFP_WAIT; // paused until the first Init ()
- m_channelSound = -1;
-}
-
-// Object's destructor.
-
-CAutoFactory::~CAutoFactory()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoFactory::DeleteObject(bool bAll)
-{
- CObject* fret;
- CObject* vehicle;
-
- if ( !bAll )
- {
- fret = SearchFret(); // transform metal?
- if ( fret != 0 )
- {
- fret->DeleteObject(); // destroys the metal
- delete fret;
- }
-
- vehicle = SearchVehicle();
- if ( vehicle != 0 )
- {
- vehicle->DeleteObject(); // destroys the vehicle
- delete vehicle;
- }
- }
-
- if ( m_channelSound != -1 )
- {
- m_sound->FlushEnvelope(m_channelSound);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_channelSound = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoFactory::Init()
-{
- m_phase = AFP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- m_time = 0.0f;
- m_lastParticule = 0.0f;
-
- m_fretPos = m_object->RetPosition(0);
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoFactory::EventProcess(const Event &event)
-{
- CObject* fret;
- CObject* vehicle;
- Math::Matrix* mat;
- CPhysics* physics;
- Math::Vector pos, speed;
- Math::Point dim;
- ObjectType type;
- float zoom, angle, prog;
- int i;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
-
- if ( m_object->RetSelect() ) // factory selected?
- {
- if ( event.event == EVENT_UPDINTERFACE )
- {
- CreateInterface(true);
- }
-
- type = OBJECT_NULL;
- if ( event.event == EVENT_OBJECT_FACTORYwa ) type = OBJECT_MOBILEwa;
- if ( event.event == EVENT_OBJECT_FACTORYta ) type = OBJECT_MOBILEta;
- if ( event.event == EVENT_OBJECT_FACTORYfa ) type = OBJECT_MOBILEfa;
- if ( event.event == EVENT_OBJECT_FACTORYia ) type = OBJECT_MOBILEia;
- if ( event.event == EVENT_OBJECT_FACTORYws ) type = OBJECT_MOBILEws;
- if ( event.event == EVENT_OBJECT_FACTORYts ) type = OBJECT_MOBILEts;
- if ( event.event == EVENT_OBJECT_FACTORYfs ) type = OBJECT_MOBILEfs;
- if ( event.event == EVENT_OBJECT_FACTORYis ) type = OBJECT_MOBILEis;
- if ( event.event == EVENT_OBJECT_FACTORYwc ) type = OBJECT_MOBILEwc;
- if ( event.event == EVENT_OBJECT_FACTORYtc ) type = OBJECT_MOBILEtc;
- if ( event.event == EVENT_OBJECT_FACTORYfc ) type = OBJECT_MOBILEfc;
- if ( event.event == EVENT_OBJECT_FACTORYic ) type = OBJECT_MOBILEic;
- if ( event.event == EVENT_OBJECT_FACTORYwi ) type = OBJECT_MOBILEwi;
- if ( event.event == EVENT_OBJECT_FACTORYti ) type = OBJECT_MOBILEti;
- if ( event.event == EVENT_OBJECT_FACTORYfi ) type = OBJECT_MOBILEfi;
- if ( event.event == EVENT_OBJECT_FACTORYii ) type = OBJECT_MOBILEii;
- if ( event.event == EVENT_OBJECT_FACTORYrt ) type = OBJECT_MOBILErt;
- if ( event.event == EVENT_OBJECT_FACTORYrc ) type = OBJECT_MOBILErc;
- if ( event.event == EVENT_OBJECT_FACTORYrr ) type = OBJECT_MOBILErr;
- if ( event.event == EVENT_OBJECT_FACTORYrs ) type = OBJECT_MOBILErs;
- if ( event.event == EVENT_OBJECT_FACTORYsa ) type = OBJECT_MOBILEsa;
-
- if ( type != OBJECT_NULL )
- {
- m_type = type;
-
- if ( m_phase != AFP_WAIT )
- {
- return false;
- }
-
- fret = SearchFret(); // transform metal?
- if ( fret == 0 )
- {
- m_displayText->DisplayError(ERR_FACTORY_NULL, m_object);
- return false;
- }
- if ( NearestVehicle() )
- {
- m_displayText->DisplayError(ERR_FACTORY_NEAR, m_object);
- return false;
- }
-
- SetBusy(true);
- InitProgressTotal(3.0f+2.0f+15.0f+2.0f+3.0f);
- UpdateInterface();
-
- fret->SetLock(true); // usable metal
- SoundManip(3.0f, 1.0f, 0.5f);
-
- m_phase = AFP_CLOSE_S;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- return true;
- }
- }
-
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- EventProgress(event.rTime);
-
- if ( m_phase == AFP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- m_phase = AFP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == AFP_CLOSE_S )
- {
- if ( m_progress < 1.0f )
- {
- for ( i=0 ; i<9 ; i++ )
- {
- zoom = 0.30f+(m_progress-0.5f+i/16.0f)*2.0f*0.70f;
- if ( zoom < 0.30f ) zoom = 0.30f;
- if ( zoom > 1.00f ) zoom = 1.00f;
- m_object->SetZoomZ( 1+i, zoom);
- m_object->SetZoomZ(10+i, zoom);
- }
- }
- else
- {
- for ( i=0 ; i<9 ; i++ )
- {
- m_object->SetZoomZ( 1+i, 1.0f);
- m_object->SetZoomZ(10+i, 1.0f);
- }
-
- SoundManip(2.0f, 1.0f, 1.2f);
-
- m_phase = AFP_CLOSE_T;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == AFP_CLOSE_T )
- {
- if ( m_progress < 1.0f )
- {
- for ( i=0 ; i<9 ; i++ )
- {
- angle = -m_progress*(Math::PI/2.0f)+Math::PI/2.0f;
- m_object->SetAngleZ( 1+i, angle);
- m_object->SetAngleZ(10+i, -angle);
- }
- }
- else
- {
- for ( i=0 ; i<9 ; i++ )
- {
- m_object->SetAngleZ( 1+i, 0.0f);
- m_object->SetAngleZ(10+i, 0.0f);
- }
-
- m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->RetPosition(0), 0.0f, 1.0f, true);
- m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 11.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP);
-
- m_phase = AFP_BUILD;
- m_progress = 0.0f;
- m_speed = 1.0f/15.0f;
- }
- }
-
- if ( m_phase == AFP_BUILD )
- {
- if ( m_progress == 0.0f )
- {
- if ( !CreateVehicle() )
- {
- fret = SearchFret(); // transform metal?
- if ( fret != 0 )
- {
- fret->SetLock(false); // metal usable again
- }
-
- if ( m_channelSound != -1 )
- {
- m_sound->FlushEnvelope(m_channelSound);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_channelSound = -1;
- }
-
- m_phase = AFP_OPEN_T;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- return true;
- }
- }
-
- if ( m_progress < 1.0f )
- {
- if ( m_type == OBJECT_MOBILErt ||
- m_type == OBJECT_MOBILErc ||
- m_type == OBJECT_MOBILErr ||
- m_type == OBJECT_MOBILErs )
- {
- prog = 1.0f-m_progress*1.5f;
- if ( prog < 0.0f ) prog = 0.0f;
- }
- else
- {
- prog = 1.0f-m_progress;
- }
- angle = powf(prog*10.0f, 2.0f)+m_object->RetAngleY(0);
-
- vehicle = SearchVehicle();
- if ( vehicle != 0 )
- {
- vehicle->SetAngleY(0, angle+Math::PI);
- vehicle->SetZoom(0, m_progress);
- }
-
- fret = SearchFret(); // transform metal?
- if ( fret != 0 )
- {
- fret->SetZoom(0, 1.0f-m_progress);
- }
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
-#if 0
- pos = m_fretPos;
- pos.x += (Math::Rand()-0.5f)*20.0f;
- pos.z += (Math::Rand()-0.5f)*20.0f;
- pos.y += 1.0f;
- speed.x = (Math::Rand()-0.5f)*12.0f;
- speed.z = (Math::Rand()-0.5f)*12.0f;
- speed.y = Math::Rand()*12.0f;
- dim.x = Math::Rand()*12.0f+10.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f);
-#else
- mat = m_object->RetWorldMatrix(0);
- pos = Math::Vector(-12.0f, 20.0f, -4.0f); // position of chimney
- pos = Math::Transform(*mat, pos);
- pos.y += 2.0f;
- pos.x += (Math::Rand()-0.5f)*2.0f;
- pos.z += (Math::Rand()-0.5f)*2.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- speed.y = 6.0f+Math::Rand()*6.0f;
- dim.x = Math::Rand()*1.5f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f);
-#endif
- }
- }
- else
- {
- m_displayText->DisplayError(INFO_FACTORY, m_object);
- SoundManip(2.0f, 1.0f, 1.2f);
-
- fret = SearchFret(); // transform metal?
- if ( fret != 0 )
- {
- fret->DeleteObject(); // removes the metal
- delete fret;
- }
-
- vehicle = SearchVehicle();
- if ( vehicle != 0 )
- {
- physics = vehicle->RetPhysics();
- if ( physics != 0 )
- {
- physics->SetFreeze(false); // can move
- }
-
- vehicle->SetLock(false); // vehicle useable
-//? vehicle->RetPhysics()->RetBrain()->StartTaskAdvance(16.0f);
- vehicle->SetAngleY(0, m_object->RetAngleY(0)+Math::PI);
- vehicle->SetZoom(0, 1.0f);
- }
-
- m_main->CreateShortcuts();
-
- m_phase = AFP_OPEN_T;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == AFP_OPEN_T )
- {
- if ( m_progress < 1.0f )
- {
- for ( i=0 ; i<9 ; i++ )
- {
- angle = -(1.0f-m_progress)*(Math::PI/2.0f)+Math::PI/2.0f;
- m_object->SetAngleZ( 1+i, angle);
- m_object->SetAngleZ(10+i, -angle);
- }
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_fretPos;
- pos.x += (Math::Rand()-0.5f)*10.0f;
- pos.z += (Math::Rand()-0.5f)*10.0f;
- pos.y += Math::Rand()*10.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- for ( i=0 ; i<9 ; i++ )
- {
- m_object->SetAngleZ( 1+i, Math::PI/2.0f);
- m_object->SetAngleZ(10+i, -Math::PI/2.0f);
- }
-
- SoundManip(3.0f, 1.0f, 0.5f);
-
- m_phase = AFP_OPEN_S;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
- }
-
- if ( m_phase == AFP_OPEN_S )
- {
- if ( m_progress < 1.0f )
- {
- for ( i=0 ; i<9 ; i++ )
- {
- zoom = 0.30f+((1.0f-m_progress)-0.5f+i/16.0f)*2.0f*0.70f;
- if ( zoom < 0.30f ) zoom = 0.30f;
- if ( zoom > 1.00f ) zoom = 1.00f;
- m_object->SetZoomZ( 1+i, zoom);
- m_object->SetZoomZ(10+i, zoom);
- }
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_fretPos;
- pos.x += (Math::Rand()-0.5f)*10.0f;
- pos.z += (Math::Rand()-0.5f)*10.0f;
- pos.y += Math::Rand()*10.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- for ( i=0 ; i<9 ; i++ )
- {
- m_object->SetZoomZ( 1+i, 0.30f);
- m_object->SetZoomZ(10+i, 0.30f);
- }
-
- SetBusy(false);
- UpdateInterface();
-
- m_phase = AFP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- return true;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoFactory::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == AFP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller
-
-bool CAutoFactory::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoFactoryPhase)OpInt(line, "aPhase", AFP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
- m_fretPos = m_object->RetPosition(0);
-
- return true;
-}
-
-
-//Seeks the cargo.
-
-CObject* CAutoFactory::SearchFret()
-{
- CObject* pObj;
- Math::Vector oPos;
- ObjectType type;
- float dist;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_METAL ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, m_fretPos);
-
- if ( dist < 8.0f ) return pObj;
- }
-
- return 0;
-}
-
-// Search if a vehicle is too close.
-
-bool CAutoFactory::NearestVehicle()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType type;
- float oRadius, dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_HUMAN &&
- type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEtg &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr &&
- type != OBJECT_MOTHER &&
- type != OBJECT_ANT &&
- type != OBJECT_SPIDER &&
- type != OBJECT_BEE &&
- type != OBJECT_WORM ) continue;
-
- if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue;
- dist = Math::Distance(oPos, cPos)-oRadius;
-
- if ( dist < 10.0f ) return true;
- }
-
- return false;
-}
-
-
-// Creates a vehicle.
-
-bool CAutoFactory::CreateVehicle()
-{
- CObject* vehicle;
- Math::Matrix* mat;
- CPhysics* physics;
- Math::Vector pos;
- float angle;
- char* name;
- int i;
-
- angle = m_object->RetAngleY(0);
-
- mat = m_object->RetWorldMatrix(0);
- if ( m_type == OBJECT_MOBILErt ||
- m_type == OBJECT_MOBILErc ||
- m_type == OBJECT_MOBILErr ||
- m_type == OBJECT_MOBILErs )
- {
- pos = Math::Vector(2.0f, 0.0f, 0.0f);
- }
- else
- {
- pos = Math::Vector(4.0f, 0.0f, 0.0f);
- }
- pos = Transform(*mat, pos);
-
- vehicle = new CObject(m_iMan);
- if ( !vehicle->CreateVehicle(pos, angle, m_type, -1.0f, false, false) )
- {
- delete vehicle;
- m_displayText->DisplayError(ERR_TOOMANY, m_object);
- return false;
- }
- vehicle->UpdateMapping();
- vehicle->SetLock(true); // not usable
- vehicle->SetRange(30.0f);
-
- physics = vehicle->RetPhysics();
- if ( physics != 0 )
- {
- physics->SetFreeze(true); // it doesn't move
- }
-
- for ( i=0 ; i<10 ; i++ )
- {
- name = m_main->RetNewScriptName(m_type, i);
- if ( name == 0 ) break;
- vehicle->ReadProgram(i, name);
- }
-
- return true;
-}
-
-// Seeking the vehicle during manufacture.
-
-CObject* CAutoFactory::SearchVehicle()
-{
- CObject* pObj;
- Math::Vector oPos;
- ObjectType type;
- float dist;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( !pObj->RetLock() ) continue;
-
- type = pObj->RetType();
- if ( type != m_type ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, m_fretPos);
-
- if ( dist < 8.0f ) return pObj;
- }
-
- return 0;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoFactory::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, dim, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- dim.x = 33.0f/640.0f;
- dim.y = 33.0f/480.0f;
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = 0.0f;
- pos.y = oy+sy*2.6f;
- ddim.x = 138.0f/640.0f;
- ddim.y = 222.0f/480.0f;
- pw->CreateGroup(pos, ddim, 6, EVENT_WINDOW3);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*8.2f;
- pw->CreateButton(pos, dim, 128+9, EVENT_OBJECT_FACTORYwa);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+10, EVENT_OBJECT_FACTORYta);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+11, EVENT_OBJECT_FACTORYfa);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+22, EVENT_OBJECT_FACTORYia);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*7.1f;
- pw->CreateButton(pos, dim, 128+12, EVENT_OBJECT_FACTORYws);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+13, EVENT_OBJECT_FACTORYts);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+14, EVENT_OBJECT_FACTORYfs);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+24, EVENT_OBJECT_FACTORYis);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*6.0f;
- pw->CreateButton(pos, dim, 128+15, EVENT_OBJECT_FACTORYwc);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+16, EVENT_OBJECT_FACTORYtc);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+17, EVENT_OBJECT_FACTORYfc);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+23, EVENT_OBJECT_FACTORYic);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*4.9f;
- pw->CreateButton(pos, dim, 128+25, EVENT_OBJECT_FACTORYwi);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+26, EVENT_OBJECT_FACTORYti);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+27, EVENT_OBJECT_FACTORYfi);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+28, EVENT_OBJECT_FACTORYii);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*3.8f;
- pw->CreateButton(pos, dim, 128+18, EVENT_OBJECT_FACTORYrt);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+19, EVENT_OBJECT_FACTORYrc);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+20, EVENT_OBJECT_FACTORYrr);
- pos.x += dim.x;
- pw->CreateButton(pos, dim, 128+29, EVENT_OBJECT_FACTORYrs);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*2.7f;
- pw->CreateButton(pos, dim, 128+21, EVENT_OBJECT_FACTORYsa);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 101, EVENT_OBJECT_TYPE);
-
- UpdateInterface();
- return true;
-}
-
-// Updates the status of all interface buttons.
-
-void CAutoFactory::UpdateInterface()
-{
- CWindow* pw;
-
- if ( !m_object->RetSelect() ) return;
-
- CAuto::UpdateInterface();
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
-
- UpdateButton(pw, EVENT_OBJECT_FACTORYwa, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYta, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYfa, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYia, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYws, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYts, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYfs, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYis, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYwc, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYtc, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYfc, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYic, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYwi, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYti, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYfi, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYii, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYrt, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYrc, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYrr, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYrs, m_bBusy);
- UpdateButton(pw, EVENT_OBJECT_FACTORYsa, m_bBusy);
-}
-
-// Updates the status of one interface button.
-
-void CAutoFactory::UpdateButton(CWindow *pw, EventMsg event, bool bBusy)
-{
- bool bEnable = true;
-
- EnableInterface(pw, event, !bBusy);
-
- if ( event == EVENT_OBJECT_FACTORYta )
- {
- bEnable = g_researchDone&RESEARCH_TANK;
- }
- if ( event == EVENT_OBJECT_FACTORYfa )
- {
- bEnable = g_researchDone&RESEARCH_FLY;
- }
- if ( event == EVENT_OBJECT_FACTORYia )
- {
- bEnable = g_researchDone&RESEARCH_iPAW;
- }
-
- if ( event == EVENT_OBJECT_FACTORYws )
- {
- bEnable = g_researchDone&RESEARCH_SNIFFER;
- }
- if ( event == EVENT_OBJECT_FACTORYts )
- {
- bEnable = ( (g_researchDone&RESEARCH_SNIFFER) &&
- (g_researchDone&RESEARCH_TANK) );
- }
- if ( event == EVENT_OBJECT_FACTORYfs )
- {
- bEnable = ( (g_researchDone&RESEARCH_SNIFFER) &&
- (g_researchDone&RESEARCH_FLY) );
- }
- if ( event == EVENT_OBJECT_FACTORYis )
- {
- bEnable = ( (g_researchDone&RESEARCH_SNIFFER) &&
- (g_researchDone&RESEARCH_iPAW) );
- }
-
- if ( event == EVENT_OBJECT_FACTORYwc )
- {
- bEnable = g_researchDone&RESEARCH_CANON;
- }
- if ( event == EVENT_OBJECT_FACTORYtc )
- {
- bEnable = ( (g_researchDone&RESEARCH_CANON) &&
- (g_researchDone&RESEARCH_TANK) );
- }
- if ( event == EVENT_OBJECT_FACTORYfc )
- {
- bEnable = ( (g_researchDone&RESEARCH_CANON) &&
- (g_researchDone&RESEARCH_FLY) );
- }
- if ( event == EVENT_OBJECT_FACTORYic )
- {
- bEnable = ( (g_researchDone&RESEARCH_CANON) &&
- (g_researchDone&RESEARCH_iPAW) );
- }
-
- if ( event == EVENT_OBJECT_FACTORYwi )
- {
- bEnable = g_researchDone&RESEARCH_iGUN;
- }
- if ( event == EVENT_OBJECT_FACTORYti )
- {
- bEnable = ( (g_researchDone&RESEARCH_iGUN) &&
- (g_researchDone&RESEARCH_TANK) );
- }
- if ( event == EVENT_OBJECT_FACTORYfi )
- {
- bEnable = ( (g_researchDone&RESEARCH_iGUN) &&
- (g_researchDone&RESEARCH_FLY) );
- }
- if ( event == EVENT_OBJECT_FACTORYii )
- {
- bEnable = ( (g_researchDone&RESEARCH_iGUN) &&
- (g_researchDone&RESEARCH_iPAW) );
- }
-
- if ( event == EVENT_OBJECT_FACTORYrt )
- {
- bEnable = ( (g_researchDone&RESEARCH_THUMP) &&
- (g_researchDone&RESEARCH_TANK) );
- }
- if ( event == EVENT_OBJECT_FACTORYrc )
- {
- bEnable = ( (g_researchDone&RESEARCH_PHAZER) &&
- (g_researchDone&RESEARCH_TANK) );
- }
- if ( event == EVENT_OBJECT_FACTORYrr )
- {
- bEnable = ( (g_researchDone&RESEARCH_RECYCLER) &&
- (g_researchDone&RESEARCH_TANK) );
- }
- if ( event == EVENT_OBJECT_FACTORYrs )
- {
- bEnable = ( (g_researchDone&RESEARCH_SHIELD) &&
- (g_researchDone&RESEARCH_TANK) );
- }
-
- if ( event == EVENT_OBJECT_FACTORYsa )
- {
- bEnable = g_researchDone&RESEARCH_SUBM;
- }
-
- DeadInterface(pw, event, bEnable);
-}
-
-// Plays the sound of the manipulator arm.
-
-void CAutoFactory::SoundManip(float time, float amplitude, float frequency)
-{
- int i;
-
- i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, true);
- m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE);
- m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE);
- m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP);
-}
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autofactory.h" + +#include "common/global.h" +#include "common/iman.h" +#include "math/geometry.h" +#include "object/robotmain.h" +#include "physics/physics.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + + + +// Object's constructor. + +CAutoFactory::CAutoFactory(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); + m_type = OBJECT_MOBILEws; + m_phase = AFP_WAIT; // paused until the first Init () + m_channelSound = -1; +} + +// Object's destructor. + +CAutoFactory::~CAutoFactory() +{ +} + + +// Destroys the object. + +void CAutoFactory::DeleteObject(bool bAll) +{ + CObject* fret; + CObject* vehicle; + + if ( !bAll ) + { + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the metal + delete fret; + } + + vehicle = SearchVehicle(); + if ( vehicle != 0 ) + { + vehicle->DeleteObject(); // destroys the vehicle + delete vehicle; + } + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoFactory::Init() +{ + m_phase = AFP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + m_time = 0.0f; + m_lastParticule = 0.0f; + + m_fretPos = m_object->RetPosition(0); + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoFactory::EventProcess(const Event &event) +{ + CObject* fret; + CObject* vehicle; + Math::Matrix* mat; + CPhysics* physics; + Math::Vector pos, speed; + Math::Point dim; + ObjectType type; + float zoom, angle, prog; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + + if ( m_object->RetSelect() ) // factory selected? + { + if ( event.event == EVENT_UPDINTERFACE ) + { + CreateInterface(true); + } + + type = OBJECT_NULL; + if ( event.event == EVENT_OBJECT_FACTORYwa ) type = OBJECT_MOBILEwa; + if ( event.event == EVENT_OBJECT_FACTORYta ) type = OBJECT_MOBILEta; + if ( event.event == EVENT_OBJECT_FACTORYfa ) type = OBJECT_MOBILEfa; + if ( event.event == EVENT_OBJECT_FACTORYia ) type = OBJECT_MOBILEia; + if ( event.event == EVENT_OBJECT_FACTORYws ) type = OBJECT_MOBILEws; + if ( event.event == EVENT_OBJECT_FACTORYts ) type = OBJECT_MOBILEts; + if ( event.event == EVENT_OBJECT_FACTORYfs ) type = OBJECT_MOBILEfs; + if ( event.event == EVENT_OBJECT_FACTORYis ) type = OBJECT_MOBILEis; + if ( event.event == EVENT_OBJECT_FACTORYwc ) type = OBJECT_MOBILEwc; + if ( event.event == EVENT_OBJECT_FACTORYtc ) type = OBJECT_MOBILEtc; + if ( event.event == EVENT_OBJECT_FACTORYfc ) type = OBJECT_MOBILEfc; + if ( event.event == EVENT_OBJECT_FACTORYic ) type = OBJECT_MOBILEic; + if ( event.event == EVENT_OBJECT_FACTORYwi ) type = OBJECT_MOBILEwi; + if ( event.event == EVENT_OBJECT_FACTORYti ) type = OBJECT_MOBILEti; + if ( event.event == EVENT_OBJECT_FACTORYfi ) type = OBJECT_MOBILEfi; + if ( event.event == EVENT_OBJECT_FACTORYii ) type = OBJECT_MOBILEii; + if ( event.event == EVENT_OBJECT_FACTORYrt ) type = OBJECT_MOBILErt; + if ( event.event == EVENT_OBJECT_FACTORYrc ) type = OBJECT_MOBILErc; + if ( event.event == EVENT_OBJECT_FACTORYrr ) type = OBJECT_MOBILErr; + if ( event.event == EVENT_OBJECT_FACTORYrs ) type = OBJECT_MOBILErs; + if ( event.event == EVENT_OBJECT_FACTORYsa ) type = OBJECT_MOBILEsa; + + if ( type != OBJECT_NULL ) + { + m_type = type; + + if ( m_phase != AFP_WAIT ) + { + return false; + } + + fret = SearchFret(); // transform metal? + if ( fret == 0 ) + { + m_displayText->DisplayError(ERR_FACTORY_NULL, m_object); + return false; + } + if ( NearestVehicle() ) + { + m_displayText->DisplayError(ERR_FACTORY_NEAR, m_object); + return false; + } + + SetBusy(true); + InitProgressTotal(3.0f+2.0f+15.0f+2.0f+3.0f); + UpdateInterface(); + + fret->SetLock(true); // usable metal + SoundManip(3.0f, 1.0f, 0.5f); + + m_phase = AFP_CLOSE_S; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + return true; + } + } + + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + EventProgress(event.rTime); + + if ( m_phase == AFP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + m_phase = AFP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AFP_CLOSE_S ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + zoom = 0.30f+(m_progress-0.5f+i/16.0f)*2.0f*0.70f; + if ( zoom < 0.30f ) zoom = 0.30f; + if ( zoom > 1.00f ) zoom = 1.00f; + m_object->SetZoomZ( 1+i, zoom); + m_object->SetZoomZ(10+i, zoom); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetZoomZ( 1+i, 1.0f); + m_object->SetZoomZ(10+i, 1.0f); + } + + SoundManip(2.0f, 1.0f, 1.2f); + + m_phase = AFP_CLOSE_T; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AFP_CLOSE_T ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + angle = -m_progress*(Math::PI/2.0f)+Math::PI/2.0f; + m_object->SetAngleZ( 1+i, angle); + m_object->SetAngleZ(10+i, -angle); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetAngleZ( 1+i, 0.0f); + m_object->SetAngleZ(10+i, 0.0f); + } + + m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->RetPosition(0), 0.0f, 1.0f, true); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 11.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); + + m_phase = AFP_BUILD; + m_progress = 0.0f; + m_speed = 1.0f/15.0f; + } + } + + if ( m_phase == AFP_BUILD ) + { + if ( m_progress == 0.0f ) + { + if ( !CreateVehicle() ) + { + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->SetLock(false); // metal usable again + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + m_phase = AFP_OPEN_T; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + return true; + } + } + + if ( m_progress < 1.0f ) + { + if ( m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs ) + { + prog = 1.0f-m_progress*1.5f; + if ( prog < 0.0f ) prog = 0.0f; + } + else + { + prog = 1.0f-m_progress; + } + angle = powf(prog*10.0f, 2.0f)+m_object->RetAngleY(0); + + vehicle = SearchVehicle(); + if ( vehicle != 0 ) + { + vehicle->SetAngleY(0, angle+Math::PI); + vehicle->SetZoom(0, m_progress); + } + + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->SetZoom(0, 1.0f-m_progress); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + +#if 0 + pos = m_fretPos; + pos.x += (Math::Rand()-0.5f)*20.0f; + pos.z += (Math::Rand()-0.5f)*20.0f; + pos.y += 1.0f; + speed.x = (Math::Rand()-0.5f)*12.0f; + speed.z = (Math::Rand()-0.5f)*12.0f; + speed.y = Math::Rand()*12.0f; + dim.x = Math::Rand()*12.0f+10.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); +#else + mat = m_object->RetWorldMatrix(0); + pos = Math::Vector(-12.0f, 20.0f, -4.0f); // position of chimney + pos = Math::Transform(*mat, pos); + pos.y += 2.0f; + pos.x += (Math::Rand()-0.5f)*2.0f; + pos.z += (Math::Rand()-0.5f)*2.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 6.0f+Math::Rand()*6.0f; + dim.x = Math::Rand()*1.5f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); +#endif + } + } + else + { + m_displayText->DisplayError(INFO_FACTORY, m_object); + SoundManip(2.0f, 1.0f, 1.2f); + + fret = SearchFret(); // transform metal? + if ( fret != 0 ) + { + fret->DeleteObject(); // removes the metal + delete fret; + } + + vehicle = SearchVehicle(); + if ( vehicle != 0 ) + { + physics = vehicle->RetPhysics(); + if ( physics != 0 ) + { + physics->SetFreeze(false); // can move + } + + vehicle->SetLock(false); // vehicle useable +//? vehicle->RetPhysics()->RetBrain()->StartTaskAdvance(16.0f); + vehicle->SetAngleY(0, m_object->RetAngleY(0)+Math::PI); + vehicle->SetZoom(0, 1.0f); + } + + m_main->CreateShortcuts(); + + m_phase = AFP_OPEN_T; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AFP_OPEN_T ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + angle = -(1.0f-m_progress)*(Math::PI/2.0f)+Math::PI/2.0f; + m_object->SetAngleZ( 1+i, angle); + m_object->SetAngleZ(10+i, -angle); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_fretPos; + pos.x += (Math::Rand()-0.5f)*10.0f; + pos.z += (Math::Rand()-0.5f)*10.0f; + pos.y += Math::Rand()*10.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetAngleZ( 1+i, Math::PI/2.0f); + m_object->SetAngleZ(10+i, -Math::PI/2.0f); + } + + SoundManip(3.0f, 1.0f, 0.5f); + + m_phase = AFP_OPEN_S; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + if ( m_phase == AFP_OPEN_S ) + { + if ( m_progress < 1.0f ) + { + for ( i=0 ; i<9 ; i++ ) + { + zoom = 0.30f+((1.0f-m_progress)-0.5f+i/16.0f)*2.0f*0.70f; + if ( zoom < 0.30f ) zoom = 0.30f; + if ( zoom > 1.00f ) zoom = 1.00f; + m_object->SetZoomZ( 1+i, zoom); + m_object->SetZoomZ(10+i, zoom); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_fretPos; + pos.x += (Math::Rand()-0.5f)*10.0f; + pos.z += (Math::Rand()-0.5f)*10.0f; + pos.y += Math::Rand()*10.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + } + } + else + { + for ( i=0 ; i<9 ; i++ ) + { + m_object->SetZoomZ( 1+i, 0.30f); + m_object->SetZoomZ(10+i, 0.30f); + } + + SetBusy(false); + UpdateInterface(); + + m_phase = AFP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return true; +} + + +// Saves all parameters of the controller. + +bool CAutoFactory::Write(char *line) +{ + char name[100]; + + if ( m_phase == AFP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller + +bool CAutoFactory::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoFactoryPhase)OpInt(line, "aPhase", AFP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + m_fretPos = m_object->RetPosition(0); + + return true; +} + + +//Seeks the cargo. + +CObject* CAutoFactory::SearchFret() +{ + CObject* pObj; + Math::Vector oPos; + ObjectType type; + float dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_METAL ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, m_fretPos); + + if ( dist < 8.0f ) return pObj; + } + + return 0; +} + +// Search if a vehicle is too close. + +bool CAutoFactory::NearestVehicle() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType type; + float oRadius, dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Math::Distance(oPos, cPos)-oRadius; + + if ( dist < 10.0f ) return true; + } + + return false; +} + + +// Creates a vehicle. + +bool CAutoFactory::CreateVehicle() +{ + CObject* vehicle; + Math::Matrix* mat; + CPhysics* physics; + Math::Vector pos; + float angle; + char* name; + int i; + + angle = m_object->RetAngleY(0); + + mat = m_object->RetWorldMatrix(0); + if ( m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs ) + { + pos = Math::Vector(2.0f, 0.0f, 0.0f); + } + else + { + pos = Math::Vector(4.0f, 0.0f, 0.0f); + } + pos = Transform(*mat, pos); + + vehicle = new CObject(m_iMan); + if ( !vehicle->CreateVehicle(pos, angle, m_type, -1.0f, false, false) ) + { + delete vehicle; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return false; + } + vehicle->UpdateMapping(); + vehicle->SetLock(true); // not usable + vehicle->SetRange(30.0f); + + physics = vehicle->RetPhysics(); + if ( physics != 0 ) + { + physics->SetFreeze(true); // it doesn't move + } + + for ( i=0 ; i<10 ; i++ ) + { + name = m_main->RetNewScriptName(m_type, i); + if ( name == 0 ) break; + vehicle->ReadProgram(i, name); + } + + return true; +} + +// Seeking the vehicle during manufacture. + +CObject* CAutoFactory::SearchVehicle() +{ + CObject* pObj; + Math::Vector oPos; + ObjectType type; + float dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != m_type ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, m_fretPos); + + if ( dist < 8.0f ) return pObj; + } + + return 0; +} + + +// Creates all the interface when the object is selected. + +bool CAutoFactory::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = 0.0f; + pos.y = oy+sy*2.6f; + ddim.x = 138.0f/640.0f; + ddim.y = 222.0f/480.0f; + pw->CreateGroup(pos, ddim, 6, EVENT_WINDOW3); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*8.2f; + pw->CreateButton(pos, dim, 128+9, EVENT_OBJECT_FACTORYwa); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+10, EVENT_OBJECT_FACTORYta); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+11, EVENT_OBJECT_FACTORYfa); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+22, EVENT_OBJECT_FACTORYia); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*7.1f; + pw->CreateButton(pos, dim, 128+12, EVENT_OBJECT_FACTORYws); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+13, EVENT_OBJECT_FACTORYts); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+14, EVENT_OBJECT_FACTORYfs); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+24, EVENT_OBJECT_FACTORYis); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*6.0f; + pw->CreateButton(pos, dim, 128+15, EVENT_OBJECT_FACTORYwc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+16, EVENT_OBJECT_FACTORYtc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+17, EVENT_OBJECT_FACTORYfc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+23, EVENT_OBJECT_FACTORYic); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*4.9f; + pw->CreateButton(pos, dim, 128+25, EVENT_OBJECT_FACTORYwi); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+26, EVENT_OBJECT_FACTORYti); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+27, EVENT_OBJECT_FACTORYfi); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+28, EVENT_OBJECT_FACTORYii); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*3.8f; + pw->CreateButton(pos, dim, 128+18, EVENT_OBJECT_FACTORYrt); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+19, EVENT_OBJECT_FACTORYrc); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+20, EVENT_OBJECT_FACTORYrr); + pos.x += dim.x; + pw->CreateButton(pos, dim, 128+29, EVENT_OBJECT_FACTORYrs); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*2.7f; + pw->CreateButton(pos, dim, 128+21, EVENT_OBJECT_FACTORYsa); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 101, EVENT_OBJECT_TYPE); + + UpdateInterface(); + return true; +} + +// Updates the status of all interface buttons. + +void CAutoFactory::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + + UpdateButton(pw, EVENT_OBJECT_FACTORYwa, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYta, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfa, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYia, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYws, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYts, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfs, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYis, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYwc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYtc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYic, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYwi, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYti, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYfi, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYii, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrt, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrc, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrr, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYrs, m_bBusy); + UpdateButton(pw, EVENT_OBJECT_FACTORYsa, m_bBusy); +} + +// Updates the status of one interface button. + +void CAutoFactory::UpdateButton(CWindow *pw, EventMsg event, bool bBusy) +{ + bool bEnable = true; + + EnableInterface(pw, event, !bBusy); + + if ( event == EVENT_OBJECT_FACTORYta ) + { + bEnable = g_researchDone&RESEARCH_TANK; + } + if ( event == EVENT_OBJECT_FACTORYfa ) + { + bEnable = g_researchDone&RESEARCH_FLY; + } + if ( event == EVENT_OBJECT_FACTORYia ) + { + bEnable = g_researchDone&RESEARCH_iPAW; + } + + if ( event == EVENT_OBJECT_FACTORYws ) + { + bEnable = g_researchDone&RESEARCH_SNIFFER; + } + if ( event == EVENT_OBJECT_FACTORYts ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYfs ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( event == EVENT_OBJECT_FACTORYis ) + { + bEnable = ( (g_researchDone&RESEARCH_SNIFFER) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( event == EVENT_OBJECT_FACTORYwc ) + { + bEnable = g_researchDone&RESEARCH_CANON; + } + if ( event == EVENT_OBJECT_FACTORYtc ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYfc ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( event == EVENT_OBJECT_FACTORYic ) + { + bEnable = ( (g_researchDone&RESEARCH_CANON) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( event == EVENT_OBJECT_FACTORYwi ) + { + bEnable = g_researchDone&RESEARCH_iGUN; + } + if ( event == EVENT_OBJECT_FACTORYti ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYfi ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_FLY) ); + } + if ( event == EVENT_OBJECT_FACTORYii ) + { + bEnable = ( (g_researchDone&RESEARCH_iGUN) && + (g_researchDone&RESEARCH_iPAW) ); + } + + if ( event == EVENT_OBJECT_FACTORYrt ) + { + bEnable = ( (g_researchDone&RESEARCH_THUMP) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYrc ) + { + bEnable = ( (g_researchDone&RESEARCH_PHAZER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYrr ) + { + bEnable = ( (g_researchDone&RESEARCH_RECYCLER) && + (g_researchDone&RESEARCH_TANK) ); + } + if ( event == EVENT_OBJECT_FACTORYrs ) + { + bEnable = ( (g_researchDone&RESEARCH_SHIELD) && + (g_researchDone&RESEARCH_TANK) ); + } + + if ( event == EVENT_OBJECT_FACTORYsa ) + { + bEnable = g_researchDone&RESEARCH_SUBM; + } + + DeadInterface(pw, event, bEnable); +} + +// Plays the sound of the manipulator arm. + +void CAutoFactory::SoundManip(float time, float amplitude, float frequency) +{ + int i; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, true); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); +} + diff --git a/src/object/auto/autofactory.h b/src/object/auto/autofactory.h index d41dd62..acbdf40 100644 --- a/src/object/auto/autofactory.h +++ b/src/object/auto/autofactory.h @@ -1,74 +1,74 @@ -// * 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/.
-
-// autofactory.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoFactoryPhase
-{
- AFP_WAIT = 1, // expected metal
- AFP_CLOSE_S = 2, // closes doors (shift)
- AFP_CLOSE_T = 3, // closes doors (turn)
- AFP_BUILD = 4, // building the vehicle
- AFP_OPEN_T = 5, // opens the doors (turn)
- AFP_OPEN_S = 6, // opens the doors (shift)
- AFP_ADVANCE = 7, // advance at the door
-};
-
-
-
-class CAutoFactory : public CAuto
-{
-public:
- CAutoFactory(CInstanceManager* iMan, CObject* object);
- ~CAutoFactory();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- void UpdateInterface();
- void UpdateButton(CWindow *pw, EventMsg event, bool bBusy);
-
- CObject* SearchFret();
- bool NearestVehicle();
- bool CreateVehicle();
- CObject* SearchVehicle();
-
- void SoundManip(float time, float amplitude, float frequency);
-
-protected:
- AutoFactoryPhase m_phase;
- float m_progress;
- float m_speed;
- float m_lastParticule;
- Math::Vector m_fretPos;
- int m_channelSound;
-};
-
+// * 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/. + +// autofactory.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoFactoryPhase +{ + AFP_WAIT = 1, // expected metal + AFP_CLOSE_S = 2, // closes doors (shift) + AFP_CLOSE_T = 3, // closes doors (turn) + AFP_BUILD = 4, // building the vehicle + AFP_OPEN_T = 5, // opens the doors (turn) + AFP_OPEN_S = 6, // opens the doors (shift) + AFP_ADVANCE = 7, // advance at the door +}; + + + +class CAutoFactory : public CAuto +{ +public: + CAutoFactory(CInstanceManager* iMan, CObject* object); + ~CAutoFactory(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + void UpdateInterface(); + void UpdateButton(CWindow *pw, EventMsg event, bool bBusy); + + CObject* SearchFret(); + bool NearestVehicle(); + bool CreateVehicle(); + CObject* SearchVehicle(); + + void SoundManip(float time, float amplitude, float frequency); + +protected: + AutoFactoryPhase m_phase; + float m_progress; + float m_speed; + float m_lastParticule; + Math::Vector m_fretPos; + int m_channelSound; +}; + diff --git a/src/object/auto/autoflag.cpp b/src/object/auto/autoflag.cpp index 2c9ebdc..ea74b17 100644 --- a/src/object/auto/autoflag.cpp +++ b/src/object/auto/autoflag.cpp @@ -1,162 +1,162 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoflag.h"
-
-#include "math/geometry.h"
-#include "old/terrain.h"
-
-
-
-#define ADJUST_ANGLE false // true -> adjusts the angles of the members
-
-
-#if ADJUST_ANGLE
-static float g_flag1 = 6.00f;
-static float g_flag2 = 0.10f;
-static float g_flag3 = 2.00f;
-#endif
-
-
-// Object's constructor.
-
-CAutoFlag::CAutoFlag(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
-}
-
-// Object's destructor.
-
-CAutoFlag::~CAutoFlag()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoFlag::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoFlag::Init()
-{
- Math::Vector wind;
- float angle;
-
- m_time = 0.0f;
- m_param = 0;
- m_progress = 0.0f;
-
- wind = m_terrain->RetWind();
- angle = Math::RotateAngle(wind.x, -wind.z);
- m_object->SetAngleY(0, angle); // directs the flag in the wind
-
- m_strong = wind.Length();
-}
-
-
-// Beginning of an action (1 = shakes).
-
-void CAutoFlag::Start(int param)
-{
- if ( m_param == 0 )
- {
- m_param = param;
- m_progress = 0.0f;
- }
-}
-
-
-// Management of an event.
-
-bool CAutoFlag::EventProcess(const Event &event)
-{
- float angle;
- int i;
-
- CAuto::EventProcess(event);
-
-#if ADJUST_ANGLE
- if ( event.event == EVENT_KEYDOWN )
- {
- if ( event.param == 'E' ) g_flag1 += 0.1f;
- if ( event.param == 'D' ) g_flag1 -= 0.1f;
- if ( event.param == 'R' ) g_flag2 += 0.1f;
- if ( event.param == 'F' ) g_flag2 -= 0.1f;
- if ( event.param == 'T' ) g_flag3 += 0.1f;
- if ( event.param == 'G' ) g_flag3 -= 0.1f;
- }
-#endif
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- if ( m_param == 1 ) // shakes?
- {
- m_progress += event.rTime*(1.0f/2.0f);
- if ( m_progress < 1.0f )
- {
- angle = sinf(m_progress*Math::PI*8.0f)*0.3f*(1.0f-m_progress);
- m_object->SetAngleX(0, angle);
- angle = sinf(m_progress*Math::PI*4.0f)*0.3f*(1.0f-m_progress);
- m_object->SetAngleZ(0, angle);
- }
- else
- {
- m_object->SetAngleX(0, 0.0f);
- m_object->SetAngleZ(0, 0.0f);
- m_param = 0;
- m_progress = 0.0f;
- }
- }
-
- if ( m_strong == 0.0f ) return true; // no wind?
-
- for ( i=0 ; i<4 ; i++ )
- {
-#if ADJUST_ANGLE
- angle = sinf(m_time*g_flag1+i*2.0f)*((i+g_flag3)*g_flag2);
-#else
- angle = sinf(m_time*6.0f+i*2.0f)*((i+2.0f)*0.1f);
-#endif
- m_object->SetAngleY(1+i, angle);
- }
-
-#if ADJUST_ANGLE
- char s[100];
- sprintf(s, "a=%.2f b=%.2f c=%.2f", g_flag1, g_flag2, g_flag3);
- m_engine->SetInfoText(4, s);
-#endif
- return true;
-}
-
-
-// Returns an error due the state of the automation
-
-Error CAutoFlag::RetError()
-{
- return ERR_OK;
-}
-
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autoflag.h" + +#include "math/geometry.h" +#include "old/terrain.h" + + + +#define ADJUST_ANGLE false // true -> adjusts the angles of the members + + +#if ADJUST_ANGLE +static float g_flag1 = 6.00f; +static float g_flag2 = 0.10f; +static float g_flag3 = 2.00f; +#endif + + +// Object's constructor. + +CAutoFlag::CAutoFlag(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); +} + +// Object's destructor. + +CAutoFlag::~CAutoFlag() +{ +} + + +// Destroys the object. + +void CAutoFlag::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoFlag::Init() +{ + Math::Vector wind; + float angle; + + m_time = 0.0f; + m_param = 0; + m_progress = 0.0f; + + wind = m_terrain->RetWind(); + angle = Math::RotateAngle(wind.x, -wind.z); + m_object->SetAngleY(0, angle); // directs the flag in the wind + + m_strong = wind.Length(); +} + + +// Beginning of an action (1 = shakes). + +void CAutoFlag::Start(int param) +{ + if ( m_param == 0 ) + { + m_param = param; + m_progress = 0.0f; + } +} + + +// Management of an event. + +bool CAutoFlag::EventProcess(const Event &event) +{ + float angle; + int i; + + CAuto::EventProcess(event); + +#if ADJUST_ANGLE + if ( event.event == EVENT_KEYDOWN ) + { + if ( event.param == 'E' ) g_flag1 += 0.1f; + if ( event.param == 'D' ) g_flag1 -= 0.1f; + if ( event.param == 'R' ) g_flag2 += 0.1f; + if ( event.param == 'F' ) g_flag2 -= 0.1f; + if ( event.param == 'T' ) g_flag3 += 0.1f; + if ( event.param == 'G' ) g_flag3 -= 0.1f; + } +#endif + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + if ( m_param == 1 ) // shakes? + { + m_progress += event.rTime*(1.0f/2.0f); + if ( m_progress < 1.0f ) + { + angle = sinf(m_progress*Math::PI*8.0f)*0.3f*(1.0f-m_progress); + m_object->SetAngleX(0, angle); + angle = sinf(m_progress*Math::PI*4.0f)*0.3f*(1.0f-m_progress); + m_object->SetAngleZ(0, angle); + } + else + { + m_object->SetAngleX(0, 0.0f); + m_object->SetAngleZ(0, 0.0f); + m_param = 0; + m_progress = 0.0f; + } + } + + if ( m_strong == 0.0f ) return true; // no wind? + + for ( i=0 ; i<4 ; i++ ) + { +#if ADJUST_ANGLE + angle = sinf(m_time*g_flag1+i*2.0f)*((i+g_flag3)*g_flag2); +#else + angle = sinf(m_time*6.0f+i*2.0f)*((i+2.0f)*0.1f); +#endif + m_object->SetAngleY(1+i, angle); + } + +#if ADJUST_ANGLE + char s[100]; + sprintf(s, "a=%.2f b=%.2f c=%.2f", g_flag1, g_flag2, g_flag3); + m_engine->SetInfoText(4, s); +#endif + return true; +} + + +// Returns an error due the state of the automation + +Error CAutoFlag::RetError() +{ + return ERR_OK; +} + + diff --git a/src/object/auto/autoflag.h b/src/object/auto/autoflag.h index b503363..fdec682 100644 --- a/src/object/auto/autoflag.h +++ b/src/object/auto/autoflag.h @@ -1,46 +1,46 @@ -// * 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/.
-
-// autoflag.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-class CAutoFlag : public CAuto
-{
-public:
- CAutoFlag(CInstanceManager* iMan, CObject* object);
- ~CAutoFlag();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- void Start(int param);
- bool EventProcess(const Event &event);
- Error RetError();
-
-protected:
-
-protected:
- float m_strong;
- int m_param;
- float m_progress;
-};
-
+// * 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/. + +// autoflag.h + +#pragma once + + +#include "object/auto/auto.h" + + + +class CAutoFlag : public CAuto +{ +public: + CAutoFlag(CInstanceManager* iMan, CObject* object); + ~CAutoFlag(); + + void DeleteObject(bool bAll=false); + + void Init(); + void Start(int param); + bool EventProcess(const Event &event); + Error RetError(); + +protected: + +protected: + float m_strong; + int m_param; + float m_progress; +}; + diff --git a/src/object/auto/autohuston.cpp b/src/object/auto/autohuston.cpp index 3495437..a96bcb8 100644 --- a/src/object/auto/autohuston.cpp +++ b/src/object/auto/autohuston.cpp @@ -1,296 +1,296 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autohuston.h"
-
-#include "ui/interface.h"
-#include "ui/window.h"
-
-
-
-
-// Object's constructor.
-
-CAutoHuston::CAutoHuston(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Math::Vector pos;
- int i;
-
- for ( i=0 ; i<HUSTONMAXLENS ; i++ )
- {
- m_lens[i].parti = -1;
- }
-
- pos = m_object->RetPosition(0);
- m_lens[0].type = PARTISELR;
- m_lens[1].type = PARTISELR;
- m_lens[2].type = PARTISELR;
- m_lens[3].type = PARTISELR;
- m_lens[0].pos = pos+Math::Vector(0.0f+13.0f, 34.0f, 30.0f );
- m_lens[1].pos = pos+Math::Vector(0.0f-13.0f, 34.0f, 30.0f );
- m_lens[2].pos = pos+Math::Vector(0.0f , 34.0f, 30.0f+13.0f);
- m_lens[3].pos = pos+Math::Vector(0.0f , 34.0f, 30.0f-13.0f);
- m_lens[0].dim = 4.0f;
- m_lens[1].dim = 4.0f;
- m_lens[2].dim = 4.0f;
- m_lens[3].dim = 4.0f;
- m_lens[0].total = 1.0f;
- m_lens[1].total = 1.0f;
- m_lens[2].total = 1.0f;
- m_lens[3].total = 1.0f;
- m_lens[0].off = 0.4f;
- m_lens[1].off = 0.4f;
- m_lens[2].off = 0.4f;
- m_lens[3].off = 0.4f;
-
- // Part under the radar.
- i = 4;
- m_lens[i].type = PARTISELR;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 9.9f, 40.1f);
- m_lens[i].dim = 1.8f;
- m_lens[i].total = 0.4f;
- m_lens[i].off = 0.2f;
- i ++;
-
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 7.2f, 34.8f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 0.7f;
- m_lens[i].off = 0.3f;
- i ++;
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 34.3f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 0.7f;
- m_lens[i].off = 0.3f;
- i ++;
- m_lens[i].type = PARTISELR;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.4f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 0.0f;
- m_lens[i].off = 0.0f;
- i ++;
- m_lens[i].type = PARTISELR;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.0f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 1.0f;
- m_lens[i].off = 0.5f;
- i ++;
-
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 8.5f, 14.0f);
- m_lens[i].dim = 1.2f;
- m_lens[i].total = 0.8f;
- m_lens[i].off = 0.2f;
- i ++;
-
- m_lens[i].type = PARTISELR;
- m_lens[i].pos = pos+Math::Vector(4.0f, 6.0f, 8.6f);
- m_lens[i].dim = 1.0f;
- m_lens[i].total = 0.9f;
- m_lens[i].off = 0.7f;
- i ++;
-
- // Part with three windows.
- m_lens[i].type = PARTISELR;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 9.9f, -19.9f);
- m_lens[i].dim = 1.0f;
- m_lens[i].total = 0.6f;
- m_lens[i].off = 0.3f;
- i ++;
-
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 7.2f, 34.8f-60.0f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 0.7f;
- m_lens[i].off = 0.3f;
- i ++;
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 34.3f-60.0f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 0.0f;
- m_lens[i].off = 0.0f;
- i ++;
- m_lens[i].type = PARTISELR;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.4f-60.0f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 0.6f;
- m_lens[i].off = 0.4f;
- i ++;
- m_lens[i].type = PARTISELR;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.0f-60.0f);
- m_lens[i].dim = 0.4f;
- m_lens[i].total = 0.8f;
- m_lens[i].off = 0.2f;
- i ++;
-
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-6.5f, 13.5f, -37.0f);
- m_lens[i].dim = 1.0f;
- m_lens[i].total = 0.0f;
- m_lens[i].off = 0.0f;
- i ++;
-
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 12.2f, -39.8f);
- m_lens[i].dim = 1.8f;
- m_lens[i].total = 1.5f;
- m_lens[i].off = 0.5f;
- i ++;
-
- m_lens[i].type = PARTISELY;
- m_lens[i].pos = pos+Math::Vector(-7.0f, 8.5f, -47.0f);
- m_lens[i].dim = 0.6f;
- m_lens[i].total = 0.7f;
- m_lens[i].off = 0.5f;
- i ++;
-
- m_lensTotal = i;
-
- Init();
-}
-
-// Object's destructor.
-
-CAutoHuston::~CAutoHuston()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoHuston::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoHuston::Init()
-{
- m_time = 0.0f;
-
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-}
-
-
-// Start the object.
-
-void CAutoHuston::Start(int param)
-{
-}
-
-
-// Management of an event.
-
-bool CAutoHuston::EventProcess(const Event &event)
-{
- Math::Vector speed;
- Math::Point dim;
- float angle;
- int i;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
-
- angle = -m_time*1.0f;
- m_object->SetAngleY(1, angle); // rotates the radar
- angle = sinf(m_time*4.0f)*0.3f;
- m_object->SetAngleX(2, angle);
-
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
-
- // Flashes the keys.
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- for ( i=0 ; i<m_lensTotal ; i++ )
- {
- if ( m_lens[i].total != 0.0f &&
- Math::Mod(m_time, m_lens[i].total) < m_lens[i].off )
- {
- if ( m_lens[i].parti != -1 )
- {
- m_particule->DeleteParticule(m_lens[i].parti);
- m_lens[i].parti = -1;
- }
- }
- else
- {
- if ( m_lens[i].parti == -1 )
- {
- dim.x = m_lens[i].dim;
- dim.y = dim.x;
- m_lens[i].parti = m_particule->CreateParticule(m_lens[i].pos, speed, dim, m_lens[i].type, 1.0f, 0.0f, 0.0f);
- }
- }
- }
-
- return true;
-}
-
-// Stops the controller.
-
-bool CAutoHuston::Abort()
-{
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoHuston::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 115, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-
-// Returns an error due to state of the automation.
-
-Error CAutoHuston::RetError()
-{
- return ERR_OK;
-}
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autohuston.h" + +#include "ui/interface.h" +#include "ui/window.h" + + + + +// Object's constructor. + +CAutoHuston::CAutoHuston(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Math::Vector pos; + int i; + + for ( i=0 ; i<HUSTONMAXLENS ; i++ ) + { + m_lens[i].parti = -1; + } + + pos = m_object->RetPosition(0); + m_lens[0].type = PARTISELR; + m_lens[1].type = PARTISELR; + m_lens[2].type = PARTISELR; + m_lens[3].type = PARTISELR; + m_lens[0].pos = pos+Math::Vector(0.0f+13.0f, 34.0f, 30.0f ); + m_lens[1].pos = pos+Math::Vector(0.0f-13.0f, 34.0f, 30.0f ); + m_lens[2].pos = pos+Math::Vector(0.0f , 34.0f, 30.0f+13.0f); + m_lens[3].pos = pos+Math::Vector(0.0f , 34.0f, 30.0f-13.0f); + m_lens[0].dim = 4.0f; + m_lens[1].dim = 4.0f; + m_lens[2].dim = 4.0f; + m_lens[3].dim = 4.0f; + m_lens[0].total = 1.0f; + m_lens[1].total = 1.0f; + m_lens[2].total = 1.0f; + m_lens[3].total = 1.0f; + m_lens[0].off = 0.4f; + m_lens[1].off = 0.4f; + m_lens[2].off = 0.4f; + m_lens[3].off = 0.4f; + + // Part under the radar. + i = 4; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+Math::Vector(-7.0f, 9.9f, 40.1f); + m_lens[i].dim = 1.8f; + m_lens[i].total = 0.4f; + m_lens[i].off = 0.2f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-7.0f, 7.2f, 34.8f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.3f; + i ++; + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 34.3f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.3f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.4f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.0f; + m_lens[i].off = 0.0f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 1.0f; + m_lens[i].off = 0.5f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-7.0f, 8.5f, 14.0f); + m_lens[i].dim = 1.2f; + m_lens[i].total = 0.8f; + m_lens[i].off = 0.2f; + i ++; + + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+Math::Vector(4.0f, 6.0f, 8.6f); + m_lens[i].dim = 1.0f; + m_lens[i].total = 0.9f; + m_lens[i].off = 0.7f; + i ++; + + // Part with three windows. + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+Math::Vector(-7.0f, 9.9f, -19.9f); + m_lens[i].dim = 1.0f; + m_lens[i].total = 0.6f; + m_lens[i].off = 0.3f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-7.0f, 7.2f, 34.8f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.3f; + i ++; + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 34.3f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.0f; + m_lens[i].off = 0.0f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.4f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.6f; + m_lens[i].off = 0.4f; + i ++; + m_lens[i].type = PARTISELR; + m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.0f-60.0f); + m_lens[i].dim = 0.4f; + m_lens[i].total = 0.8f; + m_lens[i].off = 0.2f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-6.5f, 13.5f, -37.0f); + m_lens[i].dim = 1.0f; + m_lens[i].total = 0.0f; + m_lens[i].off = 0.0f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-7.0f, 12.2f, -39.8f); + m_lens[i].dim = 1.8f; + m_lens[i].total = 1.5f; + m_lens[i].off = 0.5f; + i ++; + + m_lens[i].type = PARTISELY; + m_lens[i].pos = pos+Math::Vector(-7.0f, 8.5f, -47.0f); + m_lens[i].dim = 0.6f; + m_lens[i].total = 0.7f; + m_lens[i].off = 0.5f; + i ++; + + m_lensTotal = i; + + Init(); +} + +// Object's destructor. + +CAutoHuston::~CAutoHuston() +{ +} + + +// Destroys the object. + +void CAutoHuston::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoHuston::Init() +{ + m_time = 0.0f; + + m_progress = 0.0f; + m_speed = 1.0f/2.0f; +} + + +// Start the object. + +void CAutoHuston::Start(int param) +{ +} + + +// Management of an event. + +bool CAutoHuston::EventProcess(const Event &event) +{ + Math::Vector speed; + Math::Point dim; + float angle; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + + angle = -m_time*1.0f; + m_object->SetAngleY(1, angle); // rotates the radar + angle = sinf(m_time*4.0f)*0.3f; + m_object->SetAngleX(2, angle); + + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + + // Flashes the keys. + speed = Math::Vector(0.0f, 0.0f, 0.0f); + for ( i=0 ; i<m_lensTotal ; i++ ) + { + if ( m_lens[i].total != 0.0f && + Math::Mod(m_time, m_lens[i].total) < m_lens[i].off ) + { + if ( m_lens[i].parti != -1 ) + { + m_particule->DeleteParticule(m_lens[i].parti); + m_lens[i].parti = -1; + } + } + else + { + if ( m_lens[i].parti == -1 ) + { + dim.x = m_lens[i].dim; + dim.y = dim.x; + m_lens[i].parti = m_particule->CreateParticule(m_lens[i].pos, speed, dim, m_lens[i].type, 1.0f, 0.0f, 0.0f); + } + } + } + + return true; +} + +// Stops the controller. + +bool CAutoHuston::Abort() +{ + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoHuston::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 115, EVENT_OBJECT_TYPE); + + return true; +} + + +// Returns an error due to state of the automation. + +Error CAutoHuston::RetError() +{ + return ERR_OK; +} + diff --git a/src/object/auto/autohuston.h b/src/object/auto/autohuston.h index a12c4f2..a59f8f2 100644 --- a/src/object/auto/autohuston.h +++ b/src/object/auto/autohuston.h @@ -1,65 +1,65 @@ -// * 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/.
-
-// autohuston.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-#include "old/particule.h"
-
-
-
-struct HustonLens
-{
- int parti;
- ParticuleType type;
- Math::Vector pos;
- float dim;
- float total;
- float off;
-};
-
-
-const int HUSTONMAXLENS = 20;
-
-
-class CAutoHuston : public CAuto
-{
-public:
- CAutoHuston(CInstanceManager* iMan, CObject* object);
- ~CAutoHuston();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- void Start(int param);
- bool EventProcess(const Event &event);
- bool Abort();
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
-protected:
-
-protected:
- float m_progress;
- float m_speed;
- HustonLens m_lens[HUSTONMAXLENS];
- int m_lensTotal;
-};
-
+// * 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/. + +// autohuston.h + +#pragma once + + +#include "object/auto/auto.h" +#include "old/particule.h" + + + +struct HustonLens +{ + int parti; + ParticuleType type; + Math::Vector pos; + float dim; + float total; + float off; +}; + + +const int HUSTONMAXLENS = 20; + + +class CAutoHuston : public CAuto +{ +public: + CAutoHuston(CInstanceManager* iMan, CObject* object); + ~CAutoHuston(); + + void DeleteObject(bool bAll=false); + + void Init(); + void Start(int param); + bool EventProcess(const Event &event); + bool Abort(); + Error RetError(); + + bool CreateInterface(bool bSelect); + +protected: + +protected: + float m_progress; + float m_speed; + HustonLens m_lens[HUSTONMAXLENS]; + int m_lensTotal; +}; + diff --git a/src/object/auto/autoinfo.cpp b/src/object/auto/autoinfo.cpp index 6e00d44..56fd8c7 100644 --- a/src/object/auto/autoinfo.cpp +++ b/src/object/auto/autoinfo.cpp @@ -1,517 +1,517 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoinfo.h"
-
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/list.h"
-#include "ui/window.h"
-
-
-
-
-
-// Object's constructor.
-
-CAutoInfo::CAutoInfo(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
-}
-
-// Object's destructor.
-
-CAutoInfo::~CAutoInfo()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoInfo::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoInfo::Init()
-{
- m_phase = AIP_WAIT;
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_bLastVirus = false;
-
- CAuto::Init();
-}
-
-
-// Start a emission.
-
-void CAutoInfo::Start(int param)
-{
- Math::Vector pos, speed;
- Math::Point dim;
-
- if ( param == 0 ) // instruction "receive" ?
- {
- m_phase = AIP_EMETTE;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- else if ( param == 2 ) // instruction "send" ?
- {
- m_phase = AIP_RECEIVE;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- else
- {
- m_phase = AIP_ERROR;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
-
- m_lastParticule = 0;
- m_goal = m_object->RetPosition(0);
-
- if ( m_phase == AIP_EMETTE )
- {
- pos = m_goal;
- pos.y += 9.5f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 30.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISPHERE4, 1.5f, 0.0f, 0.0f);
-
- m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f);
- }
- if ( m_phase == AIP_RECEIVE )
- {
- pos = m_goal;
- pos.y += 9.5f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 50.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISPHERE6, 1.5f, 0.0f, 0.0f);
-
- m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f);
- }
- if ( m_phase == AIP_ERROR )
- {
- m_sound->Play(SOUND_GGG, pos, 1.0f, 0.5f);
- }
-}
-
-
-// Management of an event.
-
-bool CAutoInfo::EventProcess(const Event &event)
-{
- Math::Vector pos, speed;
- Math::Point dim;
- float duration, angle, rTime;
- int i;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
-
- angle = m_object->RetAngleY(1);
- angle += Math::Rand()*0.3f;
- m_object->SetAngleY(1, angle);
-
- m_object->SetAngleX(2, (Math::Rand()-0.5f)*0.3f);
- m_object->SetAngleX(4, (Math::Rand()-0.5f)*0.3f);
- m_object->SetAngleX(6, (Math::Rand()-0.5f)*0.3f);
-
- m_object->SetAngleZ(2, (Math::Rand()-0.5f)*0.3f);
- m_object->SetAngleZ(4, (Math::Rand()-0.5f)*0.3f);
- m_object->SetAngleZ(6, (Math::Rand()-0.5f)*0.3f);
-
- UpdateListVirus();
- }
- m_bLastVirus = true;
- return true;
- }
- else
- {
- if ( m_bLastVirus )
- {
- m_bLastVirus = false;
- UpdateList(); // normally returns the list
- }
- else
- {
- if ( m_object->RetInfoUpdate() )
- {
- UpdateList(); // updates the list
- }
- }
- }
-
- UpdateInterface(event.rTime);
-
- rTime = event.rTime;
-
- if ( m_phase == AIP_EMETTE ) // instruction "receive" ?
- {
- if ( m_progress < 0.5f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- for ( i=0 ; i<4 ; i++ )
- {
- pos = m_goal;
- pos.y += 9.5f;
- speed.x = (Math::Rand()-0.5f)*50.0f;
- speed.z = (Math::Rand()-0.5f)*50.0f;
- speed.y = (Math::Rand()-0.5f)*50.0f;
- speed *= 0.5f+m_progress*0.5f;
- dim.x = 0.6f;
- dim.y = dim.x;
- duration = Math::Rand()*0.5f+0.5f;
- m_particule->CreateTrack(pos, speed, dim, PARTITRACK6,
- duration, 0.0f,
- duration*0.9f, 0.7f);
- }
- }
-
- if ( m_progress < 1.0f )
- {
- m_progress += rTime*m_speed;
-
- m_object->SetAngleZ(2, m_progress*2.0f*Math::PI);
- m_object->SetAngleZ(4, m_progress*2.0f*Math::PI);
- m_object->SetAngleZ(6, m_progress*2.0f*Math::PI);
- }
- else
- {
- m_phase = AIP_WAIT;
-
- m_object->SetAngleX(2, 0.0f);
- m_object->SetAngleX(4, 0.0f);
- m_object->SetAngleX(6, 0.0f);
-
- m_object->SetAngleZ(2, 0.0f);
- m_object->SetAngleZ(4, 0.0f);
- m_object->SetAngleZ(6, 0.0f);
- }
- }
-
- if ( m_phase == AIP_RECEIVE ) // instruction "send" ?
- {
- if ( m_progress < 0.5f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- for ( i=0 ; i<4 ; i++ )
- {
- pos = m_goal;
- pos.y += 9.5f;
- speed = pos;
- pos.x += (Math::Rand()-0.5f)*40.0f;
- pos.y += (Math::Rand()-0.5f)*40.0f;
- pos.z += (Math::Rand()-0.5f)*40.0f;
- speed = (speed-pos)*1.0f;
-//? speed *= 0.5f+m_progress*0.5f;
- dim.x = 0.6f;
- dim.y = dim.x;
- duration = Math::Rand()*0.5f+0.5f;
- m_particule->CreateTrack(pos, speed, dim, PARTITRACK6,
- duration, 0.0f,
- duration*0.9f, 0.7f);
- }
- }
-
- if ( m_progress < 1.0f )
- {
- m_progress += rTime*m_speed;
-
- m_object->SetAngleZ(2, m_progress*2.0f*Math::PI);
- m_object->SetAngleZ(4, m_progress*2.0f*Math::PI);
- m_object->SetAngleZ(6, m_progress*2.0f*Math::PI);
- }
- else
- {
- m_phase = AIP_WAIT;
-
- m_object->SetAngleX(2, 0.0f);
- m_object->SetAngleX(4, 0.0f);
- m_object->SetAngleX(6, 0.0f);
-
- m_object->SetAngleZ(2, 0.0f);
- m_object->SetAngleZ(4, 0.0f);
- m_object->SetAngleZ(6, 0.0f);
- }
- }
-
- if ( m_phase == AIP_ERROR )
- {
- if ( m_progress < 0.5f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_goal;
- speed.x = (Math::Rand()-0.5f)*5.0f;
- speed.z = (Math::Rand()-0.5f)*5.0f;
- speed.y = 5.0f+Math::Rand()*5.0f;
- dim.x = 5.0f+Math::Rand()*5.0f;
- dim.y = dim.x;
- duration = Math::Rand()*0.5f+0.5f;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 4.0f);
- }
-
- if ( m_progress < 1.0f )
- {
- m_progress += rTime*m_speed;
- rTime = 0.0f; // stops the rotation
-
- if ( m_progress < 0.5f )
- {
- angle = m_progress/0.5f;
- }
- else
- {
- angle = 1.0f-(m_progress-0.5f)/0.5f;
- }
- m_object->SetAngleX(2, angle*0.5f);
- m_object->SetAngleX(4, angle*0.5f);
- m_object->SetAngleX(6, angle*0.5f);
-
- m_object->SetAngleZ(2, (Math::Rand()-0.5f)*0.2f);
- m_object->SetAngleZ(4, (Math::Rand()-0.5f)*0.2f);
- m_object->SetAngleZ(6, (Math::Rand()-0.5f)*0.2f);
- }
- else
- {
- m_phase = AIP_WAIT;
-
- m_object->SetAngleX(2, 0.0f);
- m_object->SetAngleX(4, 0.0f);
- m_object->SetAngleX(6, 0.0f);
-
- m_object->SetAngleZ(2, 0.0f);
- m_object->SetAngleZ(4, 0.0f);
- m_object->SetAngleZ(6, 0.0f);
- }
- }
-
- angle = m_object->RetAngleY(1);
- angle += rTime*0.5f;
- m_object->SetAngleY(1, angle);
-
- m_object->SetAngleX(3, sinf(m_time*6.0f+Math::PI*0.0f/3.0f)*0.3f);
- m_object->SetAngleX(5, sinf(m_time*6.0f+Math::PI*2.0f/3.0f)*0.3f);
- m_object->SetAngleX(7, sinf(m_time*6.0f+Math::PI*4.0f/3.0f)*0.3f);
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoInfo::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- return ERR_OK;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoInfo::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- CList* pl;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*7.0f;
- pos.y = oy+sy*0.0f;
- ddim.x = 160.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pl = pw->CreateList(pos, ddim, 1, EVENT_OBJECT_GINFO, 1.10f);
- pl->SetSelectCap(false);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 112, EVENT_OBJECT_TYPE);
-
- UpdateList();
- return true;
-}
-
-// Updates the state of all buttons on the interface,
-// following the time that elapses ...
-
-void CAutoInfo::UpdateInterface(float rTime)
-{
- CAuto::UpdateInterface(rTime);
-}
-
-
-// Updates the contents of the list.
-
-void CAutoInfo::UpdateList()
-{
- CWindow* pw;
- CList* pl;
- Info info;
- int total, i;
- char text[100];
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO);
- if ( pl == 0 ) return;
-
- pl->Flush();
- total = m_object->RetInfoTotal();
- if ( total == 0 )
- {
- pl->ClearState(STATE_ENABLE);
- }
- else
- {
- pl->SetState(STATE_ENABLE);
-
- for ( i=0 ; i<total ; i++ )
- {
- info = m_object->RetInfo(i);
- sprintf(text, "%s = %.2f", info.name, info.value);
- pl->SetName(i, text);
- }
- }
-
- m_object->SetInfoUpdate(false);
-}
-
-// Updates the content of contaminating the list.
-
-void CAutoInfo::UpdateListVirus()
-{
- CWindow* pw;
- CList* pl;
- int i, j, max;
- char text[100];
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO);
- if ( pl == 0 ) return;
-
- pl->SetState(STATE_ENABLE);
-
- pl->Flush();
- for ( i=0 ; i<4 ; i++ )
- {
- max = (int)(2.0f+Math::Rand()*10.0f);
- for ( j=0 ; j<max ; j++ )
- {
- do
- {
- text[j] = ' '+(int)(Math::Rand()*94.0f);
- }
- while ( text[j] == '\\' );
- }
- text[j] = 0;
-
- pl->SetName(i, text);
- }
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoInfo::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == AIP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoInfo::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoInfoPhase)OpInt(line, "aPhase", AIP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autoinfo.h" + +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/list.h" +#include "ui/window.h" + + + + + +// Object's constructor. + +CAutoInfo::CAutoInfo(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); +} + +// Object's destructor. + +CAutoInfo::~CAutoInfo() +{ +} + + +// Destroys the object. + +void CAutoInfo::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoInfo::Init() +{ + m_phase = AIP_WAIT; + m_time = 0.0f; + m_timeVirus = 0.0f; + m_bLastVirus = false; + + CAuto::Init(); +} + + +// Start a emission. + +void CAutoInfo::Start(int param) +{ + Math::Vector pos, speed; + Math::Point dim; + + if ( param == 0 ) // instruction "receive" ? + { + m_phase = AIP_EMETTE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else if ( param == 2 ) // instruction "send" ? + { + m_phase = AIP_RECEIVE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else + { + m_phase = AIP_ERROR; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + + m_lastParticule = 0; + m_goal = m_object->RetPosition(0); + + if ( m_phase == AIP_EMETTE ) + { + pos = m_goal; + pos.y += 9.5f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 30.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISPHERE4, 1.5f, 0.0f, 0.0f); + + m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); + } + if ( m_phase == AIP_RECEIVE ) + { + pos = m_goal; + pos.y += 9.5f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 50.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISPHERE6, 1.5f, 0.0f, 0.0f); + + m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); + } + if ( m_phase == AIP_ERROR ) + { + m_sound->Play(SOUND_GGG, pos, 1.0f, 0.5f); + } +} + + +// Management of an event. + +bool CAutoInfo::EventProcess(const Event &event) +{ + Math::Vector pos, speed; + Math::Point dim; + float duration, angle, rTime; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + angle = m_object->RetAngleY(1); + angle += Math::Rand()*0.3f; + m_object->SetAngleY(1, angle); + + m_object->SetAngleX(2, (Math::Rand()-0.5f)*0.3f); + m_object->SetAngleX(4, (Math::Rand()-0.5f)*0.3f); + m_object->SetAngleX(6, (Math::Rand()-0.5f)*0.3f); + + m_object->SetAngleZ(2, (Math::Rand()-0.5f)*0.3f); + m_object->SetAngleZ(4, (Math::Rand()-0.5f)*0.3f); + m_object->SetAngleZ(6, (Math::Rand()-0.5f)*0.3f); + + UpdateListVirus(); + } + m_bLastVirus = true; + return true; + } + else + { + if ( m_bLastVirus ) + { + m_bLastVirus = false; + UpdateList(); // normally returns the list + } + else + { + if ( m_object->RetInfoUpdate() ) + { + UpdateList(); // updates the list + } + } + } + + UpdateInterface(event.rTime); + + rTime = event.rTime; + + if ( m_phase == AIP_EMETTE ) // instruction "receive" ? + { + if ( m_progress < 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<4 ; i++ ) + { + pos = m_goal; + pos.y += 9.5f; + speed.x = (Math::Rand()-0.5f)*50.0f; + speed.z = (Math::Rand()-0.5f)*50.0f; + speed.y = (Math::Rand()-0.5f)*50.0f; + speed *= 0.5f+m_progress*0.5f; + dim.x = 0.6f; + dim.y = dim.x; + duration = Math::Rand()*0.5f+0.5f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + if ( m_progress < 1.0f ) + { + m_progress += rTime*m_speed; + + m_object->SetAngleZ(2, m_progress*2.0f*Math::PI); + m_object->SetAngleZ(4, m_progress*2.0f*Math::PI); + m_object->SetAngleZ(6, m_progress*2.0f*Math::PI); + } + else + { + m_phase = AIP_WAIT; + + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(4, 0.0f); + m_object->SetAngleX(6, 0.0f); + + m_object->SetAngleZ(2, 0.0f); + m_object->SetAngleZ(4, 0.0f); + m_object->SetAngleZ(6, 0.0f); + } + } + + if ( m_phase == AIP_RECEIVE ) // instruction "send" ? + { + if ( m_progress < 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<4 ; i++ ) + { + pos = m_goal; + pos.y += 9.5f; + speed = pos; + pos.x += (Math::Rand()-0.5f)*40.0f; + pos.y += (Math::Rand()-0.5f)*40.0f; + pos.z += (Math::Rand()-0.5f)*40.0f; + speed = (speed-pos)*1.0f; +//? speed *= 0.5f+m_progress*0.5f; + dim.x = 0.6f; + dim.y = dim.x; + duration = Math::Rand()*0.5f+0.5f; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + if ( m_progress < 1.0f ) + { + m_progress += rTime*m_speed; + + m_object->SetAngleZ(2, m_progress*2.0f*Math::PI); + m_object->SetAngleZ(4, m_progress*2.0f*Math::PI); + m_object->SetAngleZ(6, m_progress*2.0f*Math::PI); + } + else + { + m_phase = AIP_WAIT; + + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(4, 0.0f); + m_object->SetAngleX(6, 0.0f); + + m_object->SetAngleZ(2, 0.0f); + m_object->SetAngleZ(4, 0.0f); + m_object->SetAngleZ(6, 0.0f); + } + } + + if ( m_phase == AIP_ERROR ) + { + if ( m_progress < 0.5f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_goal; + speed.x = (Math::Rand()-0.5f)*5.0f; + speed.z = (Math::Rand()-0.5f)*5.0f; + speed.y = 5.0f+Math::Rand()*5.0f; + dim.x = 5.0f+Math::Rand()*5.0f; + dim.y = dim.x; + duration = Math::Rand()*0.5f+0.5f; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 4.0f); + } + + if ( m_progress < 1.0f ) + { + m_progress += rTime*m_speed; + rTime = 0.0f; // stops the rotation + + if ( m_progress < 0.5f ) + { + angle = m_progress/0.5f; + } + else + { + angle = 1.0f-(m_progress-0.5f)/0.5f; + } + m_object->SetAngleX(2, angle*0.5f); + m_object->SetAngleX(4, angle*0.5f); + m_object->SetAngleX(6, angle*0.5f); + + m_object->SetAngleZ(2, (Math::Rand()-0.5f)*0.2f); + m_object->SetAngleZ(4, (Math::Rand()-0.5f)*0.2f); + m_object->SetAngleZ(6, (Math::Rand()-0.5f)*0.2f); + } + else + { + m_phase = AIP_WAIT; + + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(4, 0.0f); + m_object->SetAngleX(6, 0.0f); + + m_object->SetAngleZ(2, 0.0f); + m_object->SetAngleZ(4, 0.0f); + m_object->SetAngleZ(6, 0.0f); + } + } + + angle = m_object->RetAngleY(1); + angle += rTime*0.5f; + m_object->SetAngleY(1, angle); + + m_object->SetAngleX(3, sinf(m_time*6.0f+Math::PI*0.0f/3.0f)*0.3f); + m_object->SetAngleX(5, sinf(m_time*6.0f+Math::PI*2.0f/3.0f)*0.3f); + m_object->SetAngleX(7, sinf(m_time*6.0f+Math::PI*4.0f/3.0f)*0.3f); + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoInfo::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +bool CAutoInfo::CreateInterface(bool bSelect) +{ + CWindow* pw; + CList* pl; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.0f; + ddim.x = 160.0f/640.0f; + ddim.y = 66.0f/480.0f; + pl = pw->CreateList(pos, ddim, 1, EVENT_OBJECT_GINFO, 1.10f); + pl->SetSelectCap(false); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 112, EVENT_OBJECT_TYPE); + + UpdateList(); + return true; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoInfo::UpdateInterface(float rTime) +{ + CAuto::UpdateInterface(rTime); +} + + +// Updates the contents of the list. + +void CAutoInfo::UpdateList() +{ + CWindow* pw; + CList* pl; + Info info; + int total, i; + char text[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); + if ( pl == 0 ) return; + + pl->Flush(); + total = m_object->RetInfoTotal(); + if ( total == 0 ) + { + pl->ClearState(STATE_ENABLE); + } + else + { + pl->SetState(STATE_ENABLE); + + for ( i=0 ; i<total ; i++ ) + { + info = m_object->RetInfo(i); + sprintf(text, "%s = %.2f", info.name, info.value); + pl->SetName(i, text); + } + } + + m_object->SetInfoUpdate(false); +} + +// Updates the content of contaminating the list. + +void CAutoInfo::UpdateListVirus() +{ + CWindow* pw; + CList* pl; + int i, j, max; + char text[100]; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); + if ( pl == 0 ) return; + + pl->SetState(STATE_ENABLE); + + pl->Flush(); + for ( i=0 ; i<4 ; i++ ) + { + max = (int)(2.0f+Math::Rand()*10.0f); + for ( j=0 ; j<max ; j++ ) + { + do + { + text[j] = ' '+(int)(Math::Rand()*94.0f); + } + while ( text[j] == '\\' ); + } + text[j] = 0; + + pl->SetName(i, text); + } +} + + +// Saves all parameters of the controller. + +bool CAutoInfo::Write(char *line) +{ + char name[100]; + + if ( m_phase == AIP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoInfo::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoInfoPhase)OpInt(line, "aPhase", AIP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autoinfo.h b/src/object/auto/autoinfo.h index cf3d1d4..cfe3c1b 100644 --- a/src/object/auto/autoinfo.h +++ b/src/object/auto/autoinfo.h @@ -1,68 +1,68 @@ -// * 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/.
-
-// autoinfo.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoInfoPhase
-{
- AIP_WAIT = 1,
- AIP_EMETTE = 2,
- AIP_RECEIVE = 3,
- AIP_ERROR = 4,
-};
-
-
-
-class CAutoInfo : public CAuto
-{
-public:
- CAutoInfo(CInstanceManager* iMan, CObject* object);
- ~CAutoInfo();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- void Start(int param);
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- void UpdateInterface(float rTime);
- void UpdateList();
- void UpdateListVirus();
-
-protected:
- AutoInfoPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- Math::Vector m_goal;
- bool m_bLastVirus;
-};
-
+// * 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/. + +// autoinfo.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoInfoPhase +{ + AIP_WAIT = 1, + AIP_EMETTE = 2, + AIP_RECEIVE = 3, + AIP_ERROR = 4, +}; + + + +class CAutoInfo : public CAuto +{ +public: + CAutoInfo(CInstanceManager* iMan, CObject* object); + ~CAutoInfo(); + + void DeleteObject(bool bAll=false); + + void Init(); + void Start(int param); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + void UpdateInterface(float rTime); + void UpdateList(); + void UpdateListVirus(); + +protected: + AutoInfoPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + Math::Vector m_goal; + bool m_bLastVirus; +}; + diff --git a/src/object/auto/autojostle.cpp b/src/object/auto/autojostle.cpp index 6917ae7..3944297 100644 --- a/src/object/auto/autojostle.cpp +++ b/src/object/auto/autojostle.cpp @@ -1,142 +1,142 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autojostle.h"
-
-
-
-
-// Object's constructor.
-
-CAutoJostle::CAutoJostle(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
-}
-
-// Object's destructor.
-
-CAutoJostle::~CAutoJostle()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoJostle::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoJostle::Init()
-{
- m_time = 0.0f;
- m_error = ERR_CONTINUE;
-
- CAuto::Init();
-}
-
-
-// Start an emission.
-
-void CAutoJostle::Start(int param, float force)
-{
- ObjectType type;
-
- if ( force < 0.0f ) force = 0.0f;
- if ( force > 1.0f ) force = 1.0f;
-
- m_force = force;
- m_progress = 0.0f;
- m_speed = 1.0f/(0.5f+force*1.0f); // 0.5 .. 1.5
- m_time = 0.0f;
- m_error = ERR_CONTINUE;
-
- type = m_object->RetType();
- if ( type >= OBJECT_PLANT5 &&
- type <= OBJECT_PLANT7 ) // clover?
- {
- m_force *= 3.0f;
- }
-}
-
-
-// Management of an event.
-
-bool CAutoJostle::EventProcess(const Event &event)
-{
- Math::Vector dir;
- float factor, angle, zoom;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- if ( m_progress < 1.0f )
- {
- m_progress += event.rTime*m_speed;
-
- if ( m_progress < 0.5f )
- {
- factor = m_progress/0.5f;
- }
- else
- {
- factor = 2.0f-m_progress/0.5f;
- }
- factor *= m_force;
-
- dir.x = sinf(m_progress*Math::PI*4.0f);
- dir.z = cosf(m_progress*Math::PI*4.0f);
-
- angle = sinf(m_time*10.0f)*factor*0.04f;
- m_object->SetAngleX(0, angle*dir.z);
- m_object->SetAngleZ(0, angle*dir.x);
-
- zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f;
- m_object->SetZoomX(0, zoom);
- zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f;
- m_object->SetZoomY(0, zoom);
- zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f;
- m_object->SetZoomZ(0, zoom);
- }
- else
- {
- m_object->SetAngleX(0, 0.0f);
- m_object->SetAngleZ(0, 0.0f);
- m_object->SetZoom(0, Math::Vector(1.0f, 1.0f, 1.0f));
- m_error = ERR_STOP;
- }
-
- return true;
-}
-
-
-// Indicates whether the controller has completed its activity.
-
-Error CAutoJostle::IsEnded()
-{
- return m_error;
-}
-
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autojostle.h" + + + + +// Object's constructor. + +CAutoJostle::CAutoJostle(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); +} + +// Object's destructor. + +CAutoJostle::~CAutoJostle() +{ +} + + +// Destroys the object. + +void CAutoJostle::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoJostle::Init() +{ + m_time = 0.0f; + m_error = ERR_CONTINUE; + + CAuto::Init(); +} + + +// Start an emission. + +void CAutoJostle::Start(int param, float force) +{ + ObjectType type; + + if ( force < 0.0f ) force = 0.0f; + if ( force > 1.0f ) force = 1.0f; + + m_force = force; + m_progress = 0.0f; + m_speed = 1.0f/(0.5f+force*1.0f); // 0.5 .. 1.5 + m_time = 0.0f; + m_error = ERR_CONTINUE; + + type = m_object->RetType(); + if ( type >= OBJECT_PLANT5 && + type <= OBJECT_PLANT7 ) // clover? + { + m_force *= 3.0f; + } +} + + +// Management of an event. + +bool CAutoJostle::EventProcess(const Event &event) +{ + Math::Vector dir; + float factor, angle, zoom; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + if ( m_progress < 1.0f ) + { + m_progress += event.rTime*m_speed; + + if ( m_progress < 0.5f ) + { + factor = m_progress/0.5f; + } + else + { + factor = 2.0f-m_progress/0.5f; + } + factor *= m_force; + + dir.x = sinf(m_progress*Math::PI*4.0f); + dir.z = cosf(m_progress*Math::PI*4.0f); + + angle = sinf(m_time*10.0f)*factor*0.04f; + m_object->SetAngleX(0, angle*dir.z); + m_object->SetAngleZ(0, angle*dir.x); + + zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f; + m_object->SetZoomX(0, zoom); + zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f; + m_object->SetZoomY(0, zoom); + zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f; + m_object->SetZoomZ(0, zoom); + } + else + { + m_object->SetAngleX(0, 0.0f); + m_object->SetAngleZ(0, 0.0f); + m_object->SetZoom(0, Math::Vector(1.0f, 1.0f, 1.0f)); + m_error = ERR_STOP; + } + + return true; +} + + +// Indicates whether the controller has completed its activity. + +Error CAutoJostle::IsEnded() +{ + return m_error; +} + + diff --git a/src/object/auto/autojostle.h b/src/object/auto/autojostle.h index c76f953..70bb5e6 100644 --- a/src/object/auto/autojostle.h +++ b/src/object/auto/autojostle.h @@ -1,48 +1,48 @@ -// * 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/.
-
-// autojostle.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-class CAutoJostle : public CAuto
-{
-public:
- CAutoJostle(CInstanceManager* iMan, CObject* object);
- ~CAutoJostle();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- void Start(int param, float force);
- bool EventProcess(const Event &event);
- Error IsEnded();
-
-protected:
-
-protected:
- float m_force;
- float m_progress;
- float m_speed;
- float m_lastParticule;
- Error m_error;
-};
-
+// * 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/. + +// autojostle.h + +#pragma once + + +#include "object/auto/auto.h" + + + +class CAutoJostle : public CAuto +{ +public: + CAutoJostle(CInstanceManager* iMan, CObject* object); + ~CAutoJostle(); + + void DeleteObject(bool bAll=false); + + void Init(); + void Start(int param, float force); + bool EventProcess(const Event &event); + Error IsEnded(); + +protected: + +protected: + float m_force; + float m_progress; + float m_speed; + float m_lastParticule; + Error m_error; +}; + diff --git a/src/object/auto/autokid.cpp b/src/object/auto/autokid.cpp index 9177aa8..e5987cc 100644 --- a/src/object/auto/autokid.cpp +++ b/src/object/auto/autokid.cpp @@ -1,201 +1,201 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autokid.h"
-
-#include "old/particule.h"
-#include "old/water.h"
-
-
-
-// Object's constructor.
-
-CAutoKid::CAutoKid(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- m_soundChannel = -1;
- Init();
-}
-
-// Object's constructor.
-
-CAutoKid::~CAutoKid()
-{
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-}
-
-
-// Destroys the object.
-
-void CAutoKid::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoKid::Init()
-{
- Math::Vector pos;
-
- m_speed = 1.0f/1.0f;
- m_progress = 0.0f;
- m_lastParticule = 0.0f;
-
- if ( m_type == OBJECT_TEEN36 ) // trunk ?
- {
- pos = m_object->RetPosition(0);
- m_speed = 1.0f/(1.0f+(Math::Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f));
- m_progress = Math::Mod(pos.x/10.0f, 1.0f);
- }
-
- if ( m_type == OBJECT_TEEN37 ) // boat?
- {
- pos = m_object->RetPosition(0);
- m_speed = 1.0f/(1.0f+(Math::Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f))*2.5f;
- m_progress = Math::Mod(pos.x/10.0f, 1.0f);
- }
-
- if ( m_type == OBJECT_TEEN38 ) // fan?
- {
- if ( m_soundChannel == -1 )
- {
-//? m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.5f, true);
- m_bSilent = false;
- }
- }
-}
-
-
-// Management of an event.
-
-bool CAutoKid::EventProcess(const Event &event)
-{
- Math::Vector vib, pos, speed;
- Math::Point dim;
-
- CAuto::EventProcess(event);
-
- if ( m_soundChannel != -1 )
- {
- if ( m_engine->RetPause() )
- {
- if ( !m_bSilent )
- {
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.1f, SOPER_CONTINUE);
- m_bSilent = true;
- }
- }
- else
- {
- if ( m_bSilent )
- {
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 0.1f, SOPER_CONTINUE);
- m_bSilent = false;
- }
- }
- }
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
-
- if ( m_type == OBJECT_TEEN36 ) // trunk?
- {
- vib.x = 0.0f;
- vib.y = sinf(m_progress)*1.0f;
- vib.z = 0.0f;
- m_object->SetLinVibration(vib);
-
- vib.x = 0.0f;
- vib.y = 0.0f;
- vib.z = sinf(m_progress*0.5f)*0.05f;
- m_object->SetCirVibration(vib);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- pos.y = m_water->RetLevel()+1.0f;
- pos.x += (Math::Rand()-0.5f)*50.0f;
- pos.z += (Math::Rand()-0.5f)*50.0f;
- speed.y = 0.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- dim.x = 50.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f);
- }
- }
-
- if ( m_type == OBJECT_TEEN37 ) // boat?
- {
- vib.x = 0.0f;
- vib.y = sinf(m_progress)*1.0f;
- vib.z = 0.0f;
- m_object->SetLinVibration(vib);
-
- vib.x = 0.0f;
- vib.y = 0.0f;
- vib.z = sinf(m_progress*0.5f)*0.15f;
- m_object->SetCirVibration(vib);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- pos.y = m_water->RetLevel()+1.0f;
- pos.x += (Math::Rand()-0.5f)*20.0f;
- pos.z += (Math::Rand()-0.5f)*20.0f;
- speed.y = 0.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- dim.x = 20.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f);
- }
- }
-
- if ( m_type == OBJECT_TEEN38 ) // fan?
- {
- m_object->SetAngleY(1, sinf(m_progress*0.6f)*0.4f);
- m_object->SetAngleX(2, m_progress*5.0f);
- }
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoKid::RetError()
-{
- return ERR_OK;
-}
-
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autokid.h" + +#include "old/particule.h" +#include "old/water.h" + + + +// Object's constructor. + +CAutoKid::CAutoKid(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + m_soundChannel = -1; + Init(); +} + +// Object's constructor. + +CAutoKid::~CAutoKid() +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } +} + + +// Destroys the object. + +void CAutoKid::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoKid::Init() +{ + Math::Vector pos; + + m_speed = 1.0f/1.0f; + m_progress = 0.0f; + m_lastParticule = 0.0f; + + if ( m_type == OBJECT_TEEN36 ) // trunk ? + { + pos = m_object->RetPosition(0); + m_speed = 1.0f/(1.0f+(Math::Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f)); + m_progress = Math::Mod(pos.x/10.0f, 1.0f); + } + + if ( m_type == OBJECT_TEEN37 ) // boat? + { + pos = m_object->RetPosition(0); + m_speed = 1.0f/(1.0f+(Math::Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f))*2.5f; + m_progress = Math::Mod(pos.x/10.0f, 1.0f); + } + + if ( m_type == OBJECT_TEEN38 ) // fan? + { + if ( m_soundChannel == -1 ) + { +//? m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.5f, true); + m_bSilent = false; + } + } +} + + +// Management of an event. + +bool CAutoKid::EventProcess(const Event &event) +{ + Math::Vector vib, pos, speed; + Math::Point dim; + + CAuto::EventProcess(event); + + if ( m_soundChannel != -1 ) + { + if ( m_engine->RetPause() ) + { + if ( !m_bSilent ) + { + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.1f, SOPER_CONTINUE); + m_bSilent = true; + } + } + else + { + if ( m_bSilent ) + { + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 0.1f, SOPER_CONTINUE); + m_bSilent = false; + } + } + } + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + + if ( m_type == OBJECT_TEEN36 ) // trunk? + { + vib.x = 0.0f; + vib.y = sinf(m_progress)*1.0f; + vib.z = 0.0f; + m_object->SetLinVibration(vib); + + vib.x = 0.0f; + vib.y = 0.0f; + vib.z = sinf(m_progress*0.5f)*0.05f; + m_object->SetCirVibration(vib); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y = m_water->RetLevel()+1.0f; + pos.x += (Math::Rand()-0.5f)*50.0f; + pos.z += (Math::Rand()-0.5f)*50.0f; + speed.y = 0.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = 50.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); + } + } + + if ( m_type == OBJECT_TEEN37 ) // boat? + { + vib.x = 0.0f; + vib.y = sinf(m_progress)*1.0f; + vib.z = 0.0f; + m_object->SetLinVibration(vib); + + vib.x = 0.0f; + vib.y = 0.0f; + vib.z = sinf(m_progress*0.5f)*0.15f; + m_object->SetCirVibration(vib); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y = m_water->RetLevel()+1.0f; + pos.x += (Math::Rand()-0.5f)*20.0f; + pos.z += (Math::Rand()-0.5f)*20.0f; + speed.y = 0.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = 20.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); + } + } + + if ( m_type == OBJECT_TEEN38 ) // fan? + { + m_object->SetAngleY(1, sinf(m_progress*0.6f)*0.4f); + m_object->SetAngleX(2, m_progress*5.0f); + } + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoKid::RetError() +{ + return ERR_OK; +} + + diff --git a/src/object/auto/autokid.h b/src/object/auto/autokid.h index 900eb92..6d4258f 100644 --- a/src/object/auto/autokid.h +++ b/src/object/auto/autokid.h @@ -1,47 +1,47 @@ -// * 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/.
-
-// autokid.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-class CAutoKid : public CAuto
-{
-public:
- CAutoKid(CInstanceManager* iMan, CObject* object);
- ~CAutoKid();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
-protected:
-
-protected:
- float m_speed;
- float m_progress;
- float m_lastParticule;
- int m_soundChannel;
- bool m_bSilent;
-};
-
+// * 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/. + +// autokid.h + +#pragma once + + +#include "object/auto/auto.h" + + + +class CAutoKid : public CAuto +{ +public: + CAutoKid(CInstanceManager* iMan, CObject* object); + ~CAutoKid(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + +protected: + +protected: + float m_speed; + float m_progress; + float m_lastParticule; + int m_soundChannel; + bool m_bSilent; +}; + diff --git a/src/object/auto/autolabo.cpp b/src/object/auto/autolabo.cpp index b675581..4239f49 100644 --- a/src/object/auto/autolabo.cpp +++ b/src/object/auto/autolabo.cpp @@ -1,610 +1,610 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autolabo.h"
-
-#include "common/global.h"
-#include "common/misc.h"
-#include "math/geometry.h"
-#include "object/robotmain.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-const float LABO_DELAY = 20.0f; // duration of the analysis
-
-
-
-
-// Object's constructor.
-
-CAutoLabo::CAutoLabo(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- int i;
-
- for ( i=0 ; i<3 ; i++ )
- {
- m_partiRank[i] = -1;
- }
- m_partiSphere = -1;
-
- m_soundChannel = -1;
- Init();
-}
-
-// Object's destructor.
-
-CAutoLabo::~CAutoLabo()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoLabo::DeleteObject(bool bAll)
-{
- int i;
-
- for ( i=0 ; i<3 ; i++ )
- {
- if ( m_partiRank[i] != -1 )
- {
- m_particule->DeleteParticule(m_partiRank[i]);
- m_partiRank[i] = -1;
- }
- }
-
- if ( m_partiSphere != -1 )
- {
- m_particule->DeleteParticule(m_partiSphere);
- m_partiSphere = -1;
- }
-
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoLabo::Init()
-{
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
-
- m_phase = ALAP_WAIT; // waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoLabo::EventProcess(const Event &event)
-{
- CObject* power;
- Math::Vector pos, goal, speed;
- Math::Point dim, rot;
- float angle;
- int i;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
-
- if ( event.event == EVENT_UPDINTERFACE )
- {
- if ( m_object->RetSelect() ) CreateInterface(true);
- }
-
- if ( m_object->RetSelect() && // center selected?
- (event.event == EVENT_OBJECT_RiPAW ||
- event.event == EVENT_OBJECT_RiGUN) )
- {
- if ( m_phase != ALAP_WAIT )
- {
- return false;
- }
-
- m_research = event.event;
-
- if ( TestResearch(m_research) )
- {
- m_displayText->DisplayError(ERR_LABO_ALREADY, m_object);
- return false;
- }
-
- power = m_object->RetPower();
- if ( power == 0 )
- {
- m_displayText->DisplayError(ERR_LABO_NULL, m_object);
- return false;
- }
- if ( power->RetType() != OBJECT_BULLET )
- {
- m_displayText->DisplayError(ERR_LABO_BAD, m_object);
- return false;
- }
-
- SetBusy(true);
- InitProgressTotal(1.0f+1.5f+1.5f+LABO_DELAY+1.5f+1.5f+1.0f);
- UpdateInterface();
-
- power->SetLock(true); // ball longer usable
-
- SoundManip(1.0f, 1.0f, 1.0f);
- m_phase = ALAP_OPEN1;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- return true;
- }
-
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
- }
- return true;
- }
-
- EventProgress(event.rTime);
-
- if ( m_phase == ALAP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- m_phase = ALAP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == ALAP_OPEN1 )
- {
- if ( m_progress < 1.0f )
- {
- angle = 80.0f-(35.0f*m_progress);
- m_object->SetAngleZ(3, angle*Math::PI/180.0f);
- m_object->SetAngleZ(4, angle*Math::PI/180.0f);
- m_object->SetAngleZ(5, angle*Math::PI/180.0f);
- }
- else
- {
- m_object->SetAngleZ(3, 45.0f*Math::PI/180.0f);
- m_object->SetAngleZ(4, 45.0f*Math::PI/180.0f);
- m_object->SetAngleZ(5, 45.0f*Math::PI/180.0f);
-
- SoundManip(1.5f, 1.0f, 0.7f);
- m_phase = ALAP_OPEN2;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
-
- if ( m_phase == ALAP_OPEN2 )
- {
- if ( m_progress < 1.0f )
- {
- pos.x = -9.0f;
- pos.y = 3.0f+m_progress*10.0f;
- pos.z = 0.0f;
- m_object->SetPosition(1, pos);
- }
- else
- {
- m_object->SetPosition(1, Math::Vector(-9.0f, 13.0f, 0.0f));
-
- SoundManip(1.5f, 1.0f, 0.5f);
- m_phase = ALAP_OPEN3;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
-
- if ( m_phase == ALAP_OPEN3 )
- {
- if ( m_progress < 1.0f )
- {
- angle = (1.0f-m_progress)*Math::PI/2.0f;
- m_object->SetAngleZ(1, angle);
- }
- else
- {
- m_object->SetAngleZ(1, 0.0f);
-
- goal = m_object->RetPosition(0);
- goal.y += 3.0f;
- pos = goal;
- pos.x -= 4.0f;
- pos.y += 4.0f;
- for ( i=0 ; i<3 ; i++ )
- {
- m_partiRank[i] = m_particule->CreateRay(pos, goal,
- PARTIRAY2,
- Math::Point(2.9f, 2.9f),
- LABO_DELAY);
- }
-
- m_soundChannel = m_sound->Play(SOUND_LABO, m_object->RetPosition(0), 0.0f, 0.25f, true);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 2.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.00f, 8.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 8.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 2.0f, SOPER_STOP);
-
- pos = m_object->RetPosition(0);
- pos.y += 4.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 4.0f;
- dim.y = dim.x;
- m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE2, LABO_DELAY, 0.0f, 0.0f);
-
- m_phase = ALAP_ANALYSE;
- m_progress = 0.0f;
- m_speed = 1.0f/LABO_DELAY;
- }
- }
-
- if ( m_phase == ALAP_ANALYSE )
- {
- if ( m_progress < 1.0f )
- {
- power = m_object->RetPower();
- if ( power != 0 )
- {
- power->SetZoom(0, 1.0f-m_progress);
- }
-
- angle = m_object->RetAngleY(2);
- if ( m_progress < 0.5f )
- {
- angle -= event.rTime*m_progress*20.0f;
- }
- else
- {
- angle -= event.rTime*(20.0f-m_progress*20.0f);
- }
- m_object->SetAngleY(2, angle); // rotates the analyzer
-
- angle += m_object->RetAngleY(0);
- for ( i=0 ; i<3 ; i++ )
- {
- rot = Math::RotatePoint(-angle, -4.0f);
- pos = m_object->RetPosition(0);
- pos.x += rot.x;
- pos.z += rot.y;
- pos.y += 3.0f+4.0f;;
- m_particule->SetPosition(m_partiRank[i], pos); // adjusts ray
-
- angle += Math::PI*2.0f/3.0f;
- }
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- if ( m_progress > 0.25f &&
- m_progress < 0.80f )
- {
- pos = m_object->RetPosition(0);
- pos.y += 3.0f;
- pos.x += (Math::Rand()-0.5f)*2.0f;
- pos.z += (Math::Rand()-0.5f)*2.0f;
- speed.y = Math::Rand()*5.0f+5.0f;
- speed.x = (Math::Rand()-0.5f)*10.0f;
- speed.z = (Math::Rand()-0.5f)*10.0f;
- dim.x = Math::Rand()*0.4f*m_progress+1.0f;
- dim.y = dim.x;
- m_particule->CreateTrack(pos, speed, dim, PARTITRACK2,
- 2.0f+2.0f*m_progress, 10.0f, 1.5f, 1.4f);
- }
- }
- }
- else
- {
- SetResearch(m_research); // research done
-
- power = m_object->RetPower();
- if ( power != 0 )
- {
- m_object->SetPower(0);
- power->DeleteObject(); // destroys the ball
- delete power;
- }
-
- m_displayText->DisplayError(INFO_LABO, m_object);
-
- SoundManip(1.5f, 1.0f, 0.5f);
- m_phase = ALAP_CLOSE1;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
-
- if ( m_phase == ALAP_CLOSE1 )
- {
- if ( m_progress < 1.0f )
- {
- angle = m_progress*Math::PI/2.0f;
- m_object->SetAngleZ(1, angle);
- }
- else
- {
- m_object->SetAngleZ(1, Math::PI/2.0f);
-
- SoundManip(1.5f, 1.0f, 0.7f);
- m_phase = ALAP_CLOSE2;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
-
- if ( m_phase == ALAP_CLOSE2 )
- {
- if ( m_progress < 1.0f )
- {
- pos.x = -9.0f;
- pos.y = 3.0f+(1.0f-m_progress)*10.0f;;
- pos.z = 0.0f;
- m_object->SetPosition(1, pos);
- }
- else
- {
- m_object->SetPosition(1, Math::Vector(-9.0f, 3.0f, 0.0f));
-
- SoundManip(1.0f, 1.0f, 1.0f);
- m_phase = ALAP_CLOSE3;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ALAP_CLOSE3 )
- {
- if ( m_progress < 1.0f )
- {
- angle = 45.0f+(35.0f*m_progress);
- m_object->SetAngleZ(3, angle*Math::PI/180.0f);
- m_object->SetAngleZ(4, angle*Math::PI/180.0f);
- m_object->SetAngleZ(5, angle*Math::PI/180.0f);
- }
- else
- {
- m_object->SetAngleZ(3, 80.0f*Math::PI/180.0f);
- m_object->SetAngleZ(4, 80.0f*Math::PI/180.0f);
- m_object->SetAngleZ(5, 80.0f*Math::PI/180.0f);
-
- SetBusy(false);
- UpdateInterface();
-
- m_phase = ALAP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoLabo::RetError()
-{
- CObject* pObj;
- ObjectType type;
-
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- pObj = m_object->RetPower();
- if ( pObj == 0 ) return ERR_LABO_NULL;
- type = pObj->RetType();
- if ( type != OBJECT_BULLET ) return ERR_LABO_BAD;
-
- return ERR_OK;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoLabo::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, dim, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- dim.x = 33.0f/640.0f;
- dim.y = 33.0f/480.0f;
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*7.0f;
- pos.y = oy+sy*0.5f;
- pw->CreateButton(pos, dim, 64+45, EVENT_OBJECT_RiPAW);
-
- pos.x = ox+sx*8.0f;
- pos.y = oy+sy*0.5f;
- pw->CreateButton(pos, dim, 64+46, EVENT_OBJECT_RiGUN);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 111, EVENT_OBJECT_TYPE);
-
- UpdateInterface();
-
- return true;
-}
-
-// Updates the status of all interface buttons.
-
-void CAutoLabo::UpdateInterface()
-{
- CWindow* pw;
-
- if ( !m_object->RetSelect() ) return;
-
- CAuto::UpdateInterface();
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- DeadInterface(pw, EVENT_OBJECT_RiPAW, g_researchEnable&RESEARCH_iPAW);
- DeadInterface(pw, EVENT_OBJECT_RiGUN, g_researchEnable&RESEARCH_iGUN);
-
- OkayButton(pw, EVENT_OBJECT_RiPAW);
- OkayButton(pw, EVENT_OBJECT_RiGUN);
-
- VisibleInterface(pw, EVENT_OBJECT_RiPAW, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RiGUN, !m_bBusy);
-}
-
-// Indicates the research conducted for a button.
-
-void CAutoLabo::OkayButton(CWindow *pw, EventMsg event)
-{
- CControl* control;
-
- control = pw->SearchControl(event);
- if ( control == 0 ) return;
-
- control->SetState(STATE_OKAY, TestResearch(event));
-}
-
-
-// Test whether a search has already been done.
-
-bool CAutoLabo::TestResearch(EventMsg event)
-{
- if ( event == EVENT_OBJECT_RiPAW ) return (g_researchDone & RESEARCH_iPAW);
- if ( event == EVENT_OBJECT_RiGUN ) return (g_researchDone & RESEARCH_iGUN);
-
- return false;
-}
-
-// Indicates a search as made.
-
-void CAutoLabo::SetResearch(EventMsg event)
-{
- Event newEvent;
-
- if ( event == EVENT_OBJECT_RiPAW ) g_researchDone |= RESEARCH_iPAW;
- if ( event == EVENT_OBJECT_RiGUN ) g_researchDone |= RESEARCH_iGUN;
-
- m_main->WriteFreeParam();
-
- m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE);
- m_event->AddEvent(newEvent);
- UpdateInterface();
-}
-
-// Plays the sound of the manipulator arm.
-
-void CAutoLabo::SoundManip(float time, float amplitude, float frequency)
-{
- int i;
-
- i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, true);
- m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE);
- m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE);
- m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP);
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoLabo::Write(char *line)
-{
- Math::Vector pos;
- char name[100];
-
- if ( m_phase == ALAP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- sprintf(name, " aResearch=%d", m_research);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoLabo::Read(char *line)
-{
- Math::Vector pos;
-
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoLaboPhase)OpInt(line, "aPhase", ALAP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
- m_research = (EventMsg)OpInt(line, "aResearch", 0);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autolabo.h" + +#include "common/global.h" +#include "common/misc.h" +#include "math/geometry.h" +#include "object/robotmain.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + +const float LABO_DELAY = 20.0f; // duration of the analysis + + + + +// Object's constructor. + +CAutoLabo::CAutoLabo(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + for ( i=0 ; i<3 ; i++ ) + { + m_partiRank[i] = -1; + } + m_partiSphere = -1; + + m_soundChannel = -1; + Init(); +} + +// Object's destructor. + +CAutoLabo::~CAutoLabo() +{ +} + + +// Destroys the object. + +void CAutoLabo::DeleteObject(bool bAll) +{ + int i; + + for ( i=0 ; i<3 ; i++ ) + { + if ( m_partiRank[i] != -1 ) + { + m_particule->DeleteParticule(m_partiRank[i]); + m_partiRank[i] = -1; + } + } + + if ( m_partiSphere != -1 ) + { + m_particule->DeleteParticule(m_partiSphere); + m_partiSphere = -1; + } + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoLabo::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + m_phase = ALAP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoLabo::EventProcess(const Event &event) +{ + CObject* power; + Math::Vector pos, goal, speed; + Math::Point dim, rot; + float angle; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + + if ( event.event == EVENT_UPDINTERFACE ) + { + if ( m_object->RetSelect() ) CreateInterface(true); + } + + if ( m_object->RetSelect() && // center selected? + (event.event == EVENT_OBJECT_RiPAW || + event.event == EVENT_OBJECT_RiGUN) ) + { + if ( m_phase != ALAP_WAIT ) + { + return false; + } + + m_research = event.event; + + if ( TestResearch(m_research) ) + { + m_displayText->DisplayError(ERR_LABO_ALREADY, m_object); + return false; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + m_displayText->DisplayError(ERR_LABO_NULL, m_object); + return false; + } + if ( power->RetType() != OBJECT_BULLET ) + { + m_displayText->DisplayError(ERR_LABO_BAD, m_object); + return false; + } + + SetBusy(true); + InitProgressTotal(1.0f+1.5f+1.5f+LABO_DELAY+1.5f+1.5f+1.0f); + UpdateInterface(); + + power->SetLock(true); // ball longer usable + + SoundManip(1.0f, 1.0f, 1.0f); + m_phase = ALAP_OPEN1; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + return true; + } + + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + } + return true; + } + + EventProgress(event.rTime); + + if ( m_phase == ALAP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + m_phase = ALAP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == ALAP_OPEN1 ) + { + if ( m_progress < 1.0f ) + { + angle = 80.0f-(35.0f*m_progress); + m_object->SetAngleZ(3, angle*Math::PI/180.0f); + m_object->SetAngleZ(4, angle*Math::PI/180.0f); + m_object->SetAngleZ(5, angle*Math::PI/180.0f); + } + else + { + m_object->SetAngleZ(3, 45.0f*Math::PI/180.0f); + m_object->SetAngleZ(4, 45.0f*Math::PI/180.0f); + m_object->SetAngleZ(5, 45.0f*Math::PI/180.0f); + + SoundManip(1.5f, 1.0f, 0.7f); + m_phase = ALAP_OPEN2; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_OPEN2 ) + { + if ( m_progress < 1.0f ) + { + pos.x = -9.0f; + pos.y = 3.0f+m_progress*10.0f; + pos.z = 0.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, Math::Vector(-9.0f, 13.0f, 0.0f)); + + SoundManip(1.5f, 1.0f, 0.5f); + m_phase = ALAP_OPEN3; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_OPEN3 ) + { + if ( m_progress < 1.0f ) + { + angle = (1.0f-m_progress)*Math::PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 0.0f); + + goal = m_object->RetPosition(0); + goal.y += 3.0f; + pos = goal; + pos.x -= 4.0f; + pos.y += 4.0f; + for ( i=0 ; i<3 ; i++ ) + { + m_partiRank[i] = m_particule->CreateRay(pos, goal, + PARTIRAY2, + Math::Point(2.9f, 2.9f), + LABO_DELAY); + } + + m_soundChannel = m_sound->Play(SOUND_LABO, m_object->RetPosition(0), 0.0f, 0.25f, true); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.00f, 8.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 8.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 2.0f, SOPER_STOP); + + pos = m_object->RetPosition(0); + pos.y += 4.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 4.0f; + dim.y = dim.x; + m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE2, LABO_DELAY, 0.0f, 0.0f); + + m_phase = ALAP_ANALYSE; + m_progress = 0.0f; + m_speed = 1.0f/LABO_DELAY; + } + } + + if ( m_phase == ALAP_ANALYSE ) + { + if ( m_progress < 1.0f ) + { + power = m_object->RetPower(); + if ( power != 0 ) + { + power->SetZoom(0, 1.0f-m_progress); + } + + angle = m_object->RetAngleY(2); + if ( m_progress < 0.5f ) + { + angle -= event.rTime*m_progress*20.0f; + } + else + { + angle -= event.rTime*(20.0f-m_progress*20.0f); + } + m_object->SetAngleY(2, angle); // rotates the analyzer + + angle += m_object->RetAngleY(0); + for ( i=0 ; i<3 ; i++ ) + { + rot = Math::RotatePoint(-angle, -4.0f); + pos = m_object->RetPosition(0); + pos.x += rot.x; + pos.z += rot.y; + pos.y += 3.0f+4.0f;; + m_particule->SetPosition(m_partiRank[i], pos); // adjusts ray + + angle += Math::PI*2.0f/3.0f; + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + if ( m_progress > 0.25f && + m_progress < 0.80f ) + { + pos = m_object->RetPosition(0); + pos.y += 3.0f; + pos.x += (Math::Rand()-0.5f)*2.0f; + pos.z += (Math::Rand()-0.5f)*2.0f; + speed.y = Math::Rand()*5.0f+5.0f; + speed.x = (Math::Rand()-0.5f)*10.0f; + speed.z = (Math::Rand()-0.5f)*10.0f; + dim.x = Math::Rand()*0.4f*m_progress+1.0f; + dim.y = dim.x; + m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, + 2.0f+2.0f*m_progress, 10.0f, 1.5f, 1.4f); + } + } + } + else + { + SetResearch(m_research); // research done + + power = m_object->RetPower(); + if ( power != 0 ) + { + m_object->SetPower(0); + power->DeleteObject(); // destroys the ball + delete power; + } + + m_displayText->DisplayError(INFO_LABO, m_object); + + SoundManip(1.5f, 1.0f, 0.5f); + m_phase = ALAP_CLOSE1; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_CLOSE1 ) + { + if ( m_progress < 1.0f ) + { + angle = m_progress*Math::PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, Math::PI/2.0f); + + SoundManip(1.5f, 1.0f, 0.7f); + m_phase = ALAP_CLOSE2; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ALAP_CLOSE2 ) + { + if ( m_progress < 1.0f ) + { + pos.x = -9.0f; + pos.y = 3.0f+(1.0f-m_progress)*10.0f;; + pos.z = 0.0f; + m_object->SetPosition(1, pos); + } + else + { + m_object->SetPosition(1, Math::Vector(-9.0f, 3.0f, 0.0f)); + + SoundManip(1.0f, 1.0f, 1.0f); + m_phase = ALAP_CLOSE3; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ALAP_CLOSE3 ) + { + if ( m_progress < 1.0f ) + { + angle = 45.0f+(35.0f*m_progress); + m_object->SetAngleZ(3, angle*Math::PI/180.0f); + m_object->SetAngleZ(4, angle*Math::PI/180.0f); + m_object->SetAngleZ(5, angle*Math::PI/180.0f); + } + else + { + m_object->SetAngleZ(3, 80.0f*Math::PI/180.0f); + m_object->SetAngleZ(4, 80.0f*Math::PI/180.0f); + m_object->SetAngleZ(5, 80.0f*Math::PI/180.0f); + + SetBusy(false); + UpdateInterface(); + + m_phase = ALAP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoLabo::RetError() +{ + CObject* pObj; + ObjectType type; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return ERR_LABO_NULL; + type = pObj->RetType(); + if ( type != OBJECT_BULLET ) return ERR_LABO_BAD; + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +bool CAutoLabo::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 64+45, EVENT_OBJECT_RiPAW); + + pos.x = ox+sx*8.0f; + pos.y = oy+sy*0.5f; + pw->CreateButton(pos, dim, 64+46, EVENT_OBJECT_RiGUN); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 111, EVENT_OBJECT_TYPE); + + UpdateInterface(); + + return true; +} + +// Updates the status of all interface buttons. + +void CAutoLabo::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + DeadInterface(pw, EVENT_OBJECT_RiPAW, g_researchEnable&RESEARCH_iPAW); + DeadInterface(pw, EVENT_OBJECT_RiGUN, g_researchEnable&RESEARCH_iGUN); + + OkayButton(pw, EVENT_OBJECT_RiPAW); + OkayButton(pw, EVENT_OBJECT_RiGUN); + + VisibleInterface(pw, EVENT_OBJECT_RiPAW, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RiGUN, !m_bBusy); +} + +// Indicates the research conducted for a button. + +void CAutoLabo::OkayButton(CWindow *pw, EventMsg event) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_OKAY, TestResearch(event)); +} + + +// Test whether a search has already been done. + +bool CAutoLabo::TestResearch(EventMsg event) +{ + if ( event == EVENT_OBJECT_RiPAW ) return (g_researchDone & RESEARCH_iPAW); + if ( event == EVENT_OBJECT_RiGUN ) return (g_researchDone & RESEARCH_iGUN); + + return false; +} + +// Indicates a search as made. + +void CAutoLabo::SetResearch(EventMsg event) +{ + Event newEvent; + + if ( event == EVENT_OBJECT_RiPAW ) g_researchDone |= RESEARCH_iPAW; + if ( event == EVENT_OBJECT_RiGUN ) g_researchDone |= RESEARCH_iGUN; + + m_main->WriteFreeParam(); + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + UpdateInterface(); +} + +// Plays the sound of the manipulator arm. + +void CAutoLabo::SoundManip(float time, float amplitude, float frequency) +{ + int i; + + i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, true); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); + m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); +} + + +// Saves all parameters of the controller. + +bool CAutoLabo::Write(char *line) +{ + Math::Vector pos; + char name[100]; + + if ( m_phase == ALAP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + sprintf(name, " aResearch=%d", m_research); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoLabo::Read(char *line) +{ + Math::Vector pos; + + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoLaboPhase)OpInt(line, "aPhase", ALAP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_research = (EventMsg)OpInt(line, "aResearch", 0); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autolabo.h b/src/object/auto/autolabo.h index d94eb9e..244e633 100644 --- a/src/object/auto/autolabo.h +++ b/src/object/auto/autolabo.h @@ -1,75 +1,75 @@ -// * 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/.
-
-// autolabo.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoLaboPhase
-{
- ALAP_WAIT = 1,
- ALAP_OPEN1 = 2,
- ALAP_OPEN2 = 3,
- ALAP_OPEN3 = 4,
- ALAP_ANALYSE = 5,
- ALAP_CLOSE1 = 6,
- ALAP_CLOSE2 = 7,
- ALAP_CLOSE3 = 8,
-};
-
-
-
-class CAutoLabo : public CAuto
-{
-public:
- CAutoLabo(CInstanceManager* iMan, CObject* object);
- ~CAutoLabo();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- void UpdateInterface();
- void OkayButton(CWindow *pw, EventMsg event);
- bool TestResearch(EventMsg event);
- void SetResearch(EventMsg event);
- void SoundManip(float time, float amplitude, float frequency);
-
-protected:
- AutoLaboPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- EventMsg m_research;
- int m_partiRank[3];
- int m_partiSphere;
- int m_soundChannel;
-};
-
+// * 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/. + +// autolabo.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoLaboPhase +{ + ALAP_WAIT = 1, + ALAP_OPEN1 = 2, + ALAP_OPEN2 = 3, + ALAP_OPEN3 = 4, + ALAP_ANALYSE = 5, + ALAP_CLOSE1 = 6, + ALAP_CLOSE2 = 7, + ALAP_CLOSE3 = 8, +}; + + + +class CAutoLabo : public CAuto +{ +public: + CAutoLabo(CInstanceManager* iMan, CObject* object); + ~CAutoLabo(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + void UpdateInterface(); + void OkayButton(CWindow *pw, EventMsg event); + bool TestResearch(EventMsg event); + void SetResearch(EventMsg event); + void SoundManip(float time, float amplitude, float frequency); + +protected: + AutoLaboPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + EventMsg m_research; + int m_partiRank[3]; + int m_partiSphere; + int m_soundChannel; +}; + diff --git a/src/object/auto/automush.cpp b/src/object/auto/automush.cpp index 366dbb5..c3eaaaf 100644 --- a/src/object/auto/automush.cpp +++ b/src/object/auto/automush.cpp @@ -1,344 +1,344 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/automush.h"
-
-#include "common/iman.h"
-#include "script/cmdtoken.h"
-
-
-
-
-// Object's constructor.
-
-CAutoMush::CAutoMush(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
-}
-
-// Object's destructor.
-
-CAutoMush::~CAutoMush()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoMush::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoMush::Init()
-{
- m_phase = AMP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/4.0f;
-
- m_time = 0.0f;
- m_lastParticule = 0.0f;
-}
-
-
-// Management of an event.
-
-bool CAutoMush::EventProcess(const Event &event)
-{
- Math::Vector pos, speed, dir;
- Math::Point dim;
- float factor, zoom, size, angle;
- int i, channel;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
-
- factor = 0.0f;
- size = 1.0f;
-
- if ( m_phase == AMP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- if ( !SearchTarget() )
- {
- m_phase = AMP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/(2.0f+Math::Rand()*2.0f);
- }
- else
- {
- m_phase = AMP_SNIF;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
- }
-
- if ( m_phase == AMP_SNIF )
- {
- if ( m_progress < 1.0f )
- {
- factor = m_progress;
- }
- else
- {
- m_phase = AMP_ZOOM;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == AMP_ZOOM )
- {
- if ( m_progress < 1.0f )
- {
- factor = 1.0f;
- size = 1.0f+m_progress*0.3f;
- }
- else
- {
- m_sound->Play(SOUND_MUSHROOM, m_object->RetPosition(0));
-
- m_phase = AMP_FIRE;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == AMP_FIRE )
- {
- if ( m_progress < 1.0f )
- {
- factor = 1.0f-m_progress;
- size = 1.0f+(1.0f-m_progress)*0.3f;
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- for ( i=0 ; i<10 ; i++ )
- {
- pos = m_object->RetPosition(0);
- pos.y += 5.0f;
- speed.x = (Math::Rand()-0.5f)*200.0f;
- speed.z = (Math::Rand()-0.5f)*200.0f;
- speed.y = -(20.0f+Math::Rand()*20.0f);
- dim.x = 1.0f;
- dim.y = dim.x;
- channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN2, 2.0f, 100.0f, 0.0f);
- m_particule->SetObjectFather(channel, m_object);
- }
- }
- }
- else
- {
- m_phase = AMP_SMOKE;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == AMP_SMOKE )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- pos.y += 5.0f;
- speed.x = (Math::Rand()-0.5f)*4.0f;
- speed.z = (Math::Rand()-0.5f)*4.0f;
- speed.y = -(0.5f+Math::Rand()*0.5f);
- dim.x = Math::Rand()*2.5f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- m_phase = AMP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/(2.0f+Math::Rand()*2.0f);
- }
- }
-
- if ( factor != 0.0f || size != 1.0f )
- {
- dir.x = sinf(m_time*Math::PI*4.0f);
- dir.z = cosf(m_time*Math::PI*4.0f);
-
- angle = sinf(m_time*10.0f)*factor*0.04f;
- m_object->SetAngleX(0, angle*dir.z);
- m_object->SetAngleZ(0, angle*dir.x);
-
- zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f;
- m_object->SetZoomX(0, zoom*size);
- zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f;
- m_object->SetZoomY(0, zoom*size);
- zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f;
- m_object->SetZoomZ(0, zoom*size);
- }
- else
- {
- m_object->SetAngleX(0, 0.0f);
- m_object->SetAngleZ(0, 0.0f);
- m_object->SetZoom(0, Math::Vector(1.0f, 1.0f, 1.0f));
- }
-
- return true;
-}
-
-
-// Seeking a nearby target.
-
-bool CAutoMush::SearchTarget()
-{
- CObject* pObj;
- Math::Vector iPos, oPos;
- ObjectType type;
- float dist;
- int i;
-
- iPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj->RetLock() ) continue;
-
- type = pObj->RetType();
- if ( type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEtg &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr &&
- type != OBJECT_DERRICK &&
- type != OBJECT_STATION &&
- type != OBJECT_FACTORY &&
- type != OBJECT_REPAIR &&
- type != OBJECT_DESTROYER&&
- type != OBJECT_CONVERT &&
- type != OBJECT_TOWER &&
- type != OBJECT_RESEARCH &&
- type != OBJECT_RADAR &&
- type != OBJECT_INFO &&
- type != OBJECT_ENERGY &&
- type != OBJECT_LABO &&
- type != OBJECT_NUCLEAR &&
- type != OBJECT_PARA &&
- type != OBJECT_HUMAN ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, iPos);
- if ( dist < 50.0f ) return true;
- }
-
- return false;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoMush::RetError()
-{
- return ERR_OK;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoMush::Write(char *line)
-{
- Math::Vector pos;
- char name[100];
-
- if ( m_phase == AMP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoMush::Read(char *line)
-{
- Math::Vector pos;
-
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoMushPhase)OpInt(line, "aPhase", AMP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/automush.h" + +#include "common/iman.h" +#include "script/cmdtoken.h" + + + + +// Object's constructor. + +CAutoMush::CAutoMush(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); +} + +// Object's destructor. + +CAutoMush::~CAutoMush() +{ +} + + +// Destroys the object. + +void CAutoMush::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoMush::Init() +{ + m_phase = AMP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + + m_time = 0.0f; + m_lastParticule = 0.0f; +} + + +// Management of an event. + +bool CAutoMush::EventProcess(const Event &event) +{ + Math::Vector pos, speed, dir; + Math::Point dim; + float factor, zoom, size, angle; + int i, channel; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + + factor = 0.0f; + size = 1.0f; + + if ( m_phase == AMP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + if ( !SearchTarget() ) + { + m_phase = AMP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/(2.0f+Math::Rand()*2.0f); + } + else + { + m_phase = AMP_SNIF; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + } + + if ( m_phase == AMP_SNIF ) + { + if ( m_progress < 1.0f ) + { + factor = m_progress; + } + else + { + m_phase = AMP_ZOOM; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == AMP_ZOOM ) + { + if ( m_progress < 1.0f ) + { + factor = 1.0f; + size = 1.0f+m_progress*0.3f; + } + else + { + m_sound->Play(SOUND_MUSHROOM, m_object->RetPosition(0)); + + m_phase = AMP_FIRE; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == AMP_FIRE ) + { + if ( m_progress < 1.0f ) + { + factor = 1.0f-m_progress; + size = 1.0f+(1.0f-m_progress)*0.3f; + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.y += 5.0f; + speed.x = (Math::Rand()-0.5f)*200.0f; + speed.z = (Math::Rand()-0.5f)*200.0f; + speed.y = -(20.0f+Math::Rand()*20.0f); + dim.x = 1.0f; + dim.y = dim.x; + channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN2, 2.0f, 100.0f, 0.0f); + m_particule->SetObjectFather(channel, m_object); + } + } + } + else + { + m_phase = AMP_SMOKE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == AMP_SMOKE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y += 5.0f; + speed.x = (Math::Rand()-0.5f)*4.0f; + speed.z = (Math::Rand()-0.5f)*4.0f; + speed.y = -(0.5f+Math::Rand()*0.5f); + dim.x = Math::Rand()*2.5f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); + } + } + else + { + m_phase = AMP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/(2.0f+Math::Rand()*2.0f); + } + } + + if ( factor != 0.0f || size != 1.0f ) + { + dir.x = sinf(m_time*Math::PI*4.0f); + dir.z = cosf(m_time*Math::PI*4.0f); + + angle = sinf(m_time*10.0f)*factor*0.04f; + m_object->SetAngleX(0, angle*dir.z); + m_object->SetAngleZ(0, angle*dir.x); + + zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f; + m_object->SetZoomX(0, zoom*size); + zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f; + m_object->SetZoomY(0, zoom*size); + zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f; + m_object->SetZoomZ(0, zoom*size); + } + else + { + m_object->SetAngleX(0, 0.0f); + m_object->SetAngleZ(0, 0.0f); + m_object->SetZoom(0, Math::Vector(1.0f, 1.0f, 1.0f)); + } + + return true; +} + + +// Seeking a nearby target. + +bool CAutoMush::SearchTarget() +{ + CObject* pObj; + Math::Vector iPos, oPos; + ObjectType type; + float dist; + int i; + + iPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_DERRICK && + type != OBJECT_STATION && + type != OBJECT_FACTORY && + type != OBJECT_REPAIR && + type != OBJECT_DESTROYER&& + type != OBJECT_CONVERT && + type != OBJECT_TOWER && + type != OBJECT_RESEARCH && + type != OBJECT_RADAR && + type != OBJECT_INFO && + type != OBJECT_ENERGY && + type != OBJECT_LABO && + type != OBJECT_NUCLEAR && + type != OBJECT_PARA && + type != OBJECT_HUMAN ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, iPos); + if ( dist < 50.0f ) return true; + } + + return false; +} + + +// Returns an error due the state of the automation. + +Error CAutoMush::RetError() +{ + return ERR_OK; +} + + +// Saves all parameters of the controller. + +bool CAutoMush::Write(char *line) +{ + Math::Vector pos; + char name[100]; + + if ( m_phase == AMP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoMush::Read(char *line) +{ + Math::Vector pos; + + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoMushPhase)OpInt(line, "aPhase", AMP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/automush.h b/src/object/auto/automush.h index 5c8d62d..113d22f 100644 --- a/src/object/auto/automush.h +++ b/src/object/auto/automush.h @@ -1,61 +1,61 @@ -// * 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/.
-
-// automush.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoMushPhase
-{
- AMP_WAIT = 1,
- AMP_SNIF = 2,
- AMP_ZOOM = 3,
- AMP_FIRE = 4,
- AMP_SMOKE = 5,
-};
-
-
-
-class CAutoMush : public CAuto
-{
-public:
- CAutoMush(CInstanceManager* iMan, CObject* object);
- ~CAutoMush();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- bool SearchTarget();
-
-protected:
- AutoMushPhase m_phase;
- float m_progress;
- float m_speed;
- 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/. + +// automush.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoMushPhase +{ + AMP_WAIT = 1, + AMP_SNIF = 2, + AMP_ZOOM = 3, + AMP_FIRE = 4, + AMP_SMOKE = 5, +}; + + + +class CAutoMush : public CAuto +{ +public: + CAutoMush(CInstanceManager* iMan, CObject* object); + ~CAutoMush(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool Write(char *line); + bool Read(char *line); + +protected: + bool SearchTarget(); + +protected: + AutoMushPhase m_phase; + float m_progress; + float m_speed; + float m_lastParticule; +}; + diff --git a/src/object/auto/autonest.cpp b/src/object/auto/autonest.cpp index a1fdf67..f3c70fb 100644 --- a/src/object/auto/autonest.cpp +++ b/src/object/auto/autonest.cpp @@ -1,275 +1,275 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autonest.h"
-
-#include "common/iman.h"
-#include "old/terrain.h"
-#include "script/cmdtoken.h"
-
-
-
-
-// Object's constructor.
-
-CAutoNest::CAutoNest(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
-}
-
-// Object's destructor.
-
-CAutoNest::~CAutoNest()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoNest::DeleteObject(bool bAll)
-{
- CObject* fret;
-
- if ( !bAll )
- {
- fret = SearchFret();
- if ( fret != 0 )
- {
- fret->DeleteObject();
- delete fret;
- }
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoNest::Init()
-{
- Math::Vector pos;
-
- m_phase = ANP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/4.0f;
-
- m_time = 0.0f;
- m_lastParticule = 0.0f;
-
- pos = m_object->RetPosition(0);
- m_terrain->MoveOnFloor(pos);
- m_fretPos = pos;
-}
-
-
-// Management of an event.
-
-bool CAutoNest::EventProcess(const Event &event)
-{
- CObject* fret;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
-
- if ( m_phase == ANP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- if ( !SearchFree(m_fretPos) )
- {
- m_phase = ANP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/4.0f;
- }
- else
- {
- CreateFret(m_fretPos, 0.0f, OBJECT_BULLET);
- m_phase = ANP_BIRTH;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- }
- }
- }
-
- if ( m_phase == ANP_BIRTH )
- {
- fret = SearchFret();
-
- if ( m_progress < 1.0f )
- {
- if ( fret != 0 )
- {
- fret->SetZoom(0, m_progress);
- }
- }
- else
- {
- if ( fret != 0 )
- {
- fret->SetZoom(0, 1.0f);
- fret->SetLock(false);
- }
-
- m_phase = ANP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/5.0f;
- }
- }
-
- return true;
-}
-
-
-// Seeks if a site is free.
-
-bool CAutoNest::SearchFree(Math::Vector pos)
-{
- CObject* pObj;
- Math::Vector sPos;
- ObjectType type;
- float sRadius, distance;
- int i, j;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type == OBJECT_NEST ) continue;
-
- j = 0;
- while ( pObj->GetCrashSphere(j++, sPos, sRadius) )
- {
- distance = Math::Distance(sPos, pos);
- distance -= sRadius;
- if ( distance < 2.0f ) return false; // location occupied
- }
- }
-
- return true; // free location
-}
-
-// Create a transportable object.
-
-void CAutoNest::CreateFret(Math::Vector pos, float angle, ObjectType type)
-{
- CObject* fret;
-
- fret = new CObject(m_iMan);
- if ( !fret->CreateResource(pos, angle, type) )
- {
- delete fret;
- return;
- }
- fret->SetLock(true); // not usable
- fret->SetZoom(0, 0.0f);
-}
-
-// Looking for the ball during manufacture.
-
-CObject* CAutoNest::SearchFret()
-{
- CObject* pObj;
- Math::Vector oPos;
- ObjectType type;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( !pObj->RetLock() ) continue;
-
- type = pObj->RetType();
- if ( type != OBJECT_BULLET ) continue;
-
- oPos = pObj->RetPosition(0);
- if ( oPos.x == m_fretPos.x &&
- oPos.z == m_fretPos.z )
- {
- return pObj;
- }
- }
-
- return 0;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoNest::RetError()
-{
- return ERR_OK;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoNest::Write(char *line)
-{
- Math::Vector pos;
- char name[100];
-
- if ( m_phase == ANP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoNest::Read(char *line)
-{
- Math::Vector pos;
-
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoNestPhase)OpInt(line, "aPhase", ANP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autonest.h" + +#include "common/iman.h" +#include "old/terrain.h" +#include "script/cmdtoken.h" + + + + +// Object's constructor. + +CAutoNest::CAutoNest(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); +} + +// Object's destructor. + +CAutoNest::~CAutoNest() +{ +} + + +// Destroys the object. + +void CAutoNest::DeleteObject(bool bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchFret(); + if ( fret != 0 ) + { + fret->DeleteObject(); + delete fret; + } + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoNest::Init() +{ + Math::Vector pos; + + m_phase = ANP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + + m_time = 0.0f; + m_lastParticule = 0.0f; + + pos = m_object->RetPosition(0); + m_terrain->MoveOnFloor(pos); + m_fretPos = pos; +} + + +// Management of an event. + +bool CAutoNest::EventProcess(const Event &event) +{ + CObject* fret; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + + if ( m_phase == ANP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + if ( !SearchFree(m_fretPos) ) + { + m_phase = ANP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + } + else + { + CreateFret(m_fretPos, 0.0f, OBJECT_BULLET); + m_phase = ANP_BIRTH; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + } + + if ( m_phase == ANP_BIRTH ) + { + fret = SearchFret(); + + if ( m_progress < 1.0f ) + { + if ( fret != 0 ) + { + fret->SetZoom(0, m_progress); + } + } + else + { + if ( fret != 0 ) + { + fret->SetZoom(0, 1.0f); + fret->SetLock(false); + } + + m_phase = ANP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/5.0f; + } + } + + return true; +} + + +// Seeks if a site is free. + +bool CAutoNest::SearchFree(Math::Vector pos) +{ + CObject* pObj; + Math::Vector sPos; + ObjectType type; + float sRadius, distance; + int i, j; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type == OBJECT_NEST ) continue; + + j = 0; + while ( pObj->GetCrashSphere(j++, sPos, sRadius) ) + { + distance = Math::Distance(sPos, pos); + distance -= sRadius; + if ( distance < 2.0f ) return false; // location occupied + } + } + + return true; // free location +} + +// Create a transportable object. + +void CAutoNest::CreateFret(Math::Vector pos, float angle, ObjectType type) +{ + CObject* fret; + + fret = new CObject(m_iMan); + if ( !fret->CreateResource(pos, angle, type) ) + { + delete fret; + return; + } + fret->SetLock(true); // not usable + fret->SetZoom(0, 0.0f); +} + +// Looking for the ball during manufacture. + +CObject* CAutoNest::SearchFret() +{ + CObject* pObj; + Math::Vector oPos; + ObjectType type; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetLock() ) continue; + + type = pObj->RetType(); + if ( type != OBJECT_BULLET ) continue; + + oPos = pObj->RetPosition(0); + if ( oPos.x == m_fretPos.x && + oPos.z == m_fretPos.z ) + { + return pObj; + } + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoNest::RetError() +{ + return ERR_OK; +} + + +// Saves all parameters of the controller. + +bool CAutoNest::Write(char *line) +{ + Math::Vector pos; + char name[100]; + + if ( m_phase == ANP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoNest::Read(char *line) +{ + Math::Vector pos; + + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoNestPhase)OpInt(line, "aPhase", ANP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autonest.h b/src/object/auto/autonest.h index e697a3b..612551d 100644 --- a/src/object/auto/autonest.h +++ b/src/object/auto/autonest.h @@ -1,61 +1,61 @@ -// * 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/.
-
-// autonest.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoNestPhase
-{
- ANP_WAIT = 1,
- ANP_BIRTH = 2, // appearance of a ball
-};
-
-
-
-class CAutoNest : public CAuto
-{
-public:
- CAutoNest(CInstanceManager* iMan, CObject* object);
- ~CAutoNest();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- bool SearchFree(Math::Vector pos);
- void CreateFret(Math::Vector pos, float angle, ObjectType type);
- CObject* SearchFret();
-
-protected:
- AutoNestPhase m_phase;
- float m_progress;
- float m_speed;
- float m_lastParticule;
- Math::Vector m_fretPos;
-};
-
+// * 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/. + +// autonest.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoNestPhase +{ + ANP_WAIT = 1, + ANP_BIRTH = 2, // appearance of a ball +}; + + + +class CAutoNest : public CAuto +{ +public: + CAutoNest(CInstanceManager* iMan, CObject* object); + ~CAutoNest(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool Write(char *line); + bool Read(char *line); + +protected: + bool SearchFree(Math::Vector pos); + void CreateFret(Math::Vector pos, float angle, ObjectType type); + CObject* SearchFret(); + +protected: + AutoNestPhase m_phase; + float m_progress; + float m_speed; + float m_lastParticule; + Math::Vector m_fretPos; +}; + diff --git a/src/object/auto/autonuclear.cpp b/src/object/auto/autonuclear.cpp index 435bfc6..05f0b29 100644 --- a/src/object/auto/autonuclear.cpp +++ b/src/object/auto/autonuclear.cpp @@ -1,484 +1,484 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autonuclear.h"
-
-#include "common/iman.h"
-#include "math/geometry.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-const float NUCLEAR_DELAY = 30.0f; // duration of the generation
-
-
-
-
-// Object's constructor.
-
-CAutoNuclear::CAutoNuclear(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- m_channelSound = -1;
- Init();
-}
-
-// Object's destructor.
-
-CAutoNuclear::~CAutoNuclear()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoNuclear::DeleteObject(bool bAll)
-{
- CObject* fret;
-
- if ( !bAll )
- {
- fret = SearchUranium();
- if ( fret != 0 )
- {
- fret->DeleteObject(); // destroys the metal
- delete fret;
- }
- }
-
- if ( m_channelSound != -1 )
- {
- m_sound->FlushEnvelope(m_channelSound);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_channelSound = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoNuclear::Init()
-{
- Math::Matrix* mat;
-
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
-
- mat = m_object->RetWorldMatrix(0);
- m_pos = Math::Transform(*mat, Math::Vector(22.0f, 4.0f, 0.0f));
-
- m_phase = ANUP_WAIT; // waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoNuclear::EventProcess(const Event &event)
-{
- CObject* fret;
- Math::Matrix* mat;
- Math::Vector pos, goal, speed;
- Math::Point dim, rot;
- float angle;
- int i, max;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
- }
- return true;
- }
-
- EventProgress(event.rTime);
-
- if ( m_phase == ANUP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- fret = SearchUranium(); // transform uranium?
- if ( fret == 0 || SearchVehicle() )
- {
- m_phase = ANUP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- else
- {
- fret->SetLock(true); // usable uranium
-
- SetBusy(true);
- InitProgressTotal(1.5f+NUCLEAR_DELAY+1.5f);
- UpdateInterface();
-
- m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f);
-
- m_phase = ANUP_CLOSE;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
- }
-
- if ( m_phase == ANUP_CLOSE )
- {
- if ( m_progress < 1.0f )
- {
- angle = (1.0f-m_progress)*(135.0f*Math::PI/180.0f);
- m_object->SetAngleZ(1, angle);
- }
- else
- {
- m_object->SetAngleZ(1, 0.0f);
-
- mat = m_object->RetWorldMatrix(0);
- max = (int)(10.0f*m_engine->RetParticuleDensity());
- for ( i=0 ; i<max ; i++ )
- {
- pos.x = 27.0f;
- pos.y = 0.0f;
- pos.z = (Math::Rand()-0.5f)*8.0f;
- pos = Transform(*mat, pos);
- speed.y = 0.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- dim.x = Math::Rand()*1.0f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH);
- }
-
- m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 1.0f);
-
- m_channelSound = m_sound->Play(SOUND_NUCLEAR, m_object->RetPosition(0), 1.0f, 0.1f, true);
- m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, NUCLEAR_DELAY-1.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP);
-
- m_phase = ANUP_GENERATE;
- m_progress = 0.0f;
- m_speed = 1.0f/NUCLEAR_DELAY;
- }
- }
-
- if ( m_phase == ANUP_GENERATE )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- pos.y += 30.0f;
- pos.x += (Math::Rand()-0.5f)*6.0f;
- pos.z += (Math::Rand()-0.5f)*6.0f;
- speed.y = Math::Rand()*15.0f+15.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- dim.x = Math::Rand()*8.0f+8.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH);
-
- pos = m_pos;
- speed.x = (Math::Rand()-0.5f)*20.0f;
- speed.y = (Math::Rand()-0.5f)*20.0f;
- speed.z = (Math::Rand()-0.5f)*20.0f;
- dim.x = 2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- fret = SearchUranium();
- if ( fret != 0 )
- {
- fret->DeleteObject(); // destroyed uranium
- delete fret;
- m_object->SetPower(0);
- }
-
- CreatePower(); // creates the atomic cell
-
- max = (int)(20.0f*m_engine->RetParticuleDensity());
- for ( i=0 ; i<max ; i++ )
- {
- pos = m_pos;
- pos.x += (Math::Rand()-0.5f)*3.0f;
- pos.y += (Math::Rand()-0.5f)*3.0f;
- pos.z += (Math::Rand()-0.5f)*3.0f;
- speed.y = 0.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- dim.x = Math::Rand()*2.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, Math::Rand()*5.0f+5.0f, 0.0f, 0.0f);
- }
-
- m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f);
-
- m_phase = ANUP_OPEN;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
-
- if ( m_phase == ANUP_OPEN )
- {
- if ( m_progress < 1.0f )
- {
- angle = m_progress*(135.0f*Math::PI/180.0f);
- m_object->SetAngleZ(1, angle);
- }
- else
- {
- m_object->SetAngleZ(1, 135.0f*Math::PI/180.0f);
-
- SetBusy(false);
- UpdateInterface();
-
- m_displayText->DisplayError(INFO_NUCLEAR, m_object);
-
- m_phase = ANUP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoNuclear::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 110, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-
-// Seeking the uranium.
-
-CObject* CAutoNuclear::SearchUranium()
-{
- CObject* pObj;
-
- pObj = m_object->RetPower();
- if ( pObj == 0 ) return 0;
- if ( pObj->RetType() == OBJECT_URANIUM ) return pObj;
- return 0;
-}
-
-// Seeks if a vehicle is too close.
-
-bool CAutoNuclear::SearchVehicle()
-{
- CObject* pObj;
- Math::Vector oPos;
- ObjectType type;
- float oRadius, dist;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_HUMAN &&
- type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEtg &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr &&
- type != OBJECT_MOTHER &&
- type != OBJECT_ANT &&
- type != OBJECT_SPIDER &&
- type != OBJECT_BEE &&
- type != OBJECT_WORM ) continue;
-
- if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue;
- dist = Math::Distance(oPos, m_pos)-oRadius;
-
- if ( dist < 10.0f ) return true;
- }
-
- return false;
-}
-
-// Creates an object stack.
-
-void CAutoNuclear::CreatePower()
-{
- CObject* power;
- Math::Vector pos;
- float angle;
-
- pos = m_object->RetPosition(0);
- angle = m_object->RetAngleY(0);
-
- power = new CObject(m_iMan);
- if ( !power->CreateResource(pos, angle, OBJECT_ATOMIC) )
- {
- delete power;
- m_displayText->DisplayError(ERR_TOOMANY, m_object);
- return;
- }
-
- power->SetTruck(m_object);
- power->SetPosition(0, Math::Vector(22.0f, 3.0f, 0.0f));
- m_object->SetPower(power);
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoNuclear::RetError()
-{
- CObject* pObj;
- ObjectType type;
-//? TerrainRes res;
-
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
-//? res = m_terrain->RetResource(m_object->RetPosition(0));
-//? if ( res != TR_POWER ) return ERR_NUCLEAR_NULL;
-
-//? if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW;
-
- pObj = m_object->RetPower();
- if ( pObj == 0 ) return ERR_NUCLEAR_EMPTY;
- if ( pObj->RetLock() ) return ERR_OK;
- type = pObj->RetType();
- if ( type == OBJECT_ATOMIC ) return ERR_OK;
- if ( type != OBJECT_URANIUM ) return ERR_NUCLEAR_BAD;
-
- return ERR_OK;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoNuclear::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ANUP_STOP ||
- m_phase == ANUP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoNuclear::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoNuclearPhase)OpInt(line, "aPhase", ANUP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autonuclear.h" + +#include "common/iman.h" +#include "math/geometry.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + +const float NUCLEAR_DELAY = 30.0f; // duration of the generation + + + + +// Object's constructor. + +CAutoNuclear::CAutoNuclear(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + m_channelSound = -1; + Init(); +} + +// Object's destructor. + +CAutoNuclear::~CAutoNuclear() +{ +} + + +// Destroys the object. + +void CAutoNuclear::DeleteObject(bool bAll) +{ + CObject* fret; + + if ( !bAll ) + { + fret = SearchUranium(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroys the metal + delete fret; + } + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoNuclear::Init() +{ + Math::Matrix* mat; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + mat = m_object->RetWorldMatrix(0); + m_pos = Math::Transform(*mat, Math::Vector(22.0f, 4.0f, 0.0f)); + + m_phase = ANUP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoNuclear::EventProcess(const Event &event) +{ + CObject* fret; + Math::Matrix* mat; + Math::Vector pos, goal, speed; + Math::Point dim, rot; + float angle; + int i, max; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + } + return true; + } + + EventProgress(event.rTime); + + if ( m_phase == ANUP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + fret = SearchUranium(); // transform uranium? + if ( fret == 0 || SearchVehicle() ) + { + m_phase = ANUP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else + { + fret->SetLock(true); // usable uranium + + SetBusy(true); + InitProgressTotal(1.5f+NUCLEAR_DELAY+1.5f); + UpdateInterface(); + + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); + + m_phase = ANUP_CLOSE; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + } + + if ( m_phase == ANUP_CLOSE ) + { + if ( m_progress < 1.0f ) + { + angle = (1.0f-m_progress)*(135.0f*Math::PI/180.0f); + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 0.0f); + + mat = m_object->RetWorldMatrix(0); + max = (int)(10.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; i<max ; i++ ) + { + pos.x = 27.0f; + pos.y = 0.0f; + pos.z = (Math::Rand()-0.5f)*8.0f; + pos = Transform(*mat, pos); + speed.y = 0.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = Math::Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH); + } + + m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 1.0f); + + m_channelSound = m_sound->Play(SOUND_NUCLEAR, m_object->RetPosition(0), 1.0f, 0.1f, true); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, NUCLEAR_DELAY-1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); + + m_phase = ANUP_GENERATE; + m_progress = 0.0f; + m_speed = 1.0f/NUCLEAR_DELAY; + } + } + + if ( m_phase == ANUP_GENERATE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.y += 30.0f; + pos.x += (Math::Rand()-0.5f)*6.0f; + pos.z += (Math::Rand()-0.5f)*6.0f; + speed.y = Math::Rand()*15.0f+15.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = Math::Rand()*8.0f+8.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH); + + pos = m_pos; + speed.x = (Math::Rand()-0.5f)*20.0f; + speed.y = (Math::Rand()-0.5f)*20.0f; + speed.z = (Math::Rand()-0.5f)*20.0f; + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + } + } + else + { + fret = SearchUranium(); + if ( fret != 0 ) + { + fret->DeleteObject(); // destroyed uranium + delete fret; + m_object->SetPower(0); + } + + CreatePower(); // creates the atomic cell + + max = (int)(20.0f*m_engine->RetParticuleDensity()); + for ( i=0 ; i<max ; i++ ) + { + pos = m_pos; + pos.x += (Math::Rand()-0.5f)*3.0f; + pos.y += (Math::Rand()-0.5f)*3.0f; + pos.z += (Math::Rand()-0.5f)*3.0f; + speed.y = 0.0f; + speed.x = 0.0f; + speed.z = 0.0f; + dim.x = Math::Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, Math::Rand()*5.0f+5.0f, 0.0f, 0.0f); + } + + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); + + m_phase = ANUP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ANUP_OPEN ) + { + if ( m_progress < 1.0f ) + { + angle = m_progress*(135.0f*Math::PI/180.0f); + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 135.0f*Math::PI/180.0f); + + SetBusy(false); + UpdateInterface(); + + m_displayText->DisplayError(INFO_NUCLEAR, m_object); + + m_phase = ANUP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoNuclear::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 110, EVENT_OBJECT_TYPE); + + return true; +} + + +// Seeking the uranium. + +CObject* CAutoNuclear::SearchUranium() +{ + CObject* pObj; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return 0; + if ( pObj->RetType() == OBJECT_URANIUM ) return pObj; + return 0; +} + +// Seeks if a vehicle is too close. + +bool CAutoNuclear::SearchVehicle() +{ + CObject* pObj; + Math::Vector oPos; + ObjectType type; + float oRadius, dist; + int i; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr && + type != OBJECT_MOTHER && + type != OBJECT_ANT && + type != OBJECT_SPIDER && + type != OBJECT_BEE && + type != OBJECT_WORM ) continue; + + if ( !pObj->GetCrashSphere(0, oPos, oRadius) ) continue; + dist = Math::Distance(oPos, m_pos)-oRadius; + + if ( dist < 10.0f ) return true; + } + + return false; +} + +// Creates an object stack. + +void CAutoNuclear::CreatePower() +{ + CObject* power; + Math::Vector pos; + float angle; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngleY(0); + + power = new CObject(m_iMan); + if ( !power->CreateResource(pos, angle, OBJECT_ATOMIC) ) + { + delete power; + m_displayText->DisplayError(ERR_TOOMANY, m_object); + return; + } + + power->SetTruck(m_object); + power->SetPosition(0, Math::Vector(22.0f, 3.0f, 0.0f)); + m_object->SetPower(power); +} + + +// Returns an error due the state of the automation. + +Error CAutoNuclear::RetError() +{ + CObject* pObj; + ObjectType type; +//? TerrainRes res; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + +//? res = m_terrain->RetResource(m_object->RetPosition(0)); +//? if ( res != TR_POWER ) return ERR_NUCLEAR_NULL; + +//? if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW; + + pObj = m_object->RetPower(); + if ( pObj == 0 ) return ERR_NUCLEAR_EMPTY; + if ( pObj->RetLock() ) return ERR_OK; + type = pObj->RetType(); + if ( type == OBJECT_ATOMIC ) return ERR_OK; + if ( type != OBJECT_URANIUM ) return ERR_NUCLEAR_BAD; + + return ERR_OK; +} + + +// Saves all parameters of the controller. + +bool CAutoNuclear::Write(char *line) +{ + char name[100]; + + if ( m_phase == ANUP_STOP || + m_phase == ANUP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoNuclear::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoNuclearPhase)OpInt(line, "aPhase", ANUP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autonuclear.h b/src/object/auto/autonuclear.h index 3054887..8a4b0da 100644 --- a/src/object/auto/autonuclear.h +++ b/src/object/auto/autonuclear.h @@ -1,68 +1,68 @@ -// * 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/.
-
-// autonuclear.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoNuclearPhase
-{
- ANUP_STOP = 1,
- ANUP_WAIT = 2,
- ANUP_CLOSE = 3,
- ANUP_GENERATE = 4,
- ANUP_OPEN = 5,
-};
-
-
-
-class CAutoNuclear : public CAuto
-{
-public:
- CAutoNuclear(CInstanceManager* iMan, CObject* object);
- ~CAutoNuclear();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- CObject* SearchUranium();
- bool SearchVehicle();
- void CreatePower();
-
-protected:
- AutoNuclearPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- Math::Vector m_pos;
- int m_channelSound;
-};
-
+// * 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/. + +// autonuclear.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoNuclearPhase +{ + ANUP_STOP = 1, + ANUP_WAIT = 2, + ANUP_CLOSE = 3, + ANUP_GENERATE = 4, + ANUP_OPEN = 5, +}; + + + +class CAutoNuclear : public CAuto +{ +public: + CAutoNuclear(CInstanceManager* iMan, CObject* object); + ~CAutoNuclear(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + CObject* SearchUranium(); + bool SearchVehicle(); + void CreatePower(); + +protected: + AutoNuclearPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + Math::Vector m_pos; + int m_channelSound; +}; + diff --git a/src/object/auto/autopara.cpp b/src/object/auto/autopara.cpp index 31e214d..80ce90a 100644 --- a/src/object/auto/autopara.cpp +++ b/src/object/auto/autopara.cpp @@ -1,327 +1,327 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autopara.h"
-
-
-#include "common/iman.h"
-#include "math/geometry.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-
-
-
-
-// Object's constructor.
-
-CAutoPara::CAutoPara(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- m_channelSound = -1;
- Init();
-}
-
-// Object's destructor.
-
-CAutoPara::~CAutoPara()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoPara::DeleteObject(bool bAll)
-{
- if ( m_channelSound != -1 )
- {
- m_sound->FlushEnvelope(m_channelSound);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_channelSound = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoPara::Init()
-{
- Math::Matrix* mat;
-
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
-
- mat = m_object->RetWorldMatrix(0);
- m_pos = Math::Transform(*mat, Math::Vector(22.0f, 4.0f, 0.0f));
-
- m_phase = APAP_WAIT; // waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- CAuto::Init();
-}
-
-
-// Reception of lightning.
-
-void CAutoPara::StartBlitz()
-{
- m_phase = APAP_BLITZ;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-}
-
-
-// Management of an event.
-
-bool CAutoPara::EventProcess(const Event &event)
-{
- Math::Vector pos, speed;
- Math::Point dim;
- int i;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
- }
- return true;
- }
-
- EventProgress(event.rTime);
-
- if ( m_phase == APAP_BLITZ )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- for ( i=0 ; i<10 ; i++ )
- {
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*m_progress*40.0f;
- pos.z += (Math::Rand()-0.5f)*m_progress*40.0f;
- pos.y += 50.0f-m_progress*50.0f;
- speed.x = (Math::Rand()-0.5f)*20.0f;
- speed.z = (Math::Rand()-0.5f)*20.0f;
- speed.y = 5.0f+Math::Rand()*5.0f;
- dim.x = 2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 20.0f, 0.5f);
- }
- }
- }
- else
- {
- m_phase = APAP_CHARGE;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_phase == APAP_CHARGE )
- {
- if ( m_progress < 1.0f )
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- for ( i=0 ; i<2 ; i++ )
- {
- pos = m_object->RetPosition(0);
- pos.y += 16.0f;
- speed.x = (Math::Rand()-0.5f)*10.0f;
- speed.z = (Math::Rand()-0.5f)*10.0f;
- speed.y = -Math::Rand()*30.0f;
- dim.x = 1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f);
- }
- }
-
- ChargeObject(event.rTime);
- }
- else
- {
- m_phase = APAP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoPara::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 113, EVENT_OBJECT_TYPE);
-
- pos.x = ox+sx*10.2f;
- pos.y = oy+sy*0.5f;
- ddim.x = 33.0f/640.0f;
- ddim.y = 33.0f/480.0f;
- pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT);
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoPara::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
- return ERR_OK;
-}
-
-
-// Load all objects under the lightning rod.
-
-void CAutoPara::ChargeObject(float rTime)
-{
- CObject* pObj;
- CObject* power;
- Math::Vector sPos, oPos;
- float dist, energy;
- int i;
-
- sPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, sPos);
- if ( dist > 20.0f ) continue;
-
- if ( pObj->RetTruck() == 0 && pObj->RetType() == OBJECT_POWER )
- {
- energy = pObj->RetEnergy();
- energy += rTime/2.0f;
- if ( energy > 1.0f ) energy = 1.0f;
- pObj->SetEnergy(energy);
- }
-
- power = pObj->RetPower();
- if ( power != 0 && power->RetType() == OBJECT_POWER )
- {
- energy = power->RetEnergy();
- energy += rTime/2.0f;
- if ( energy > 1.0f ) energy = 1.0f;
- power->SetEnergy(energy);
- }
-
- power = pObj->RetFret();
- if ( power != 0 && power->RetType() == OBJECT_POWER )
- {
- energy = power->RetEnergy();
- energy += rTime/2.0f;
- if ( energy > 1.0f ) energy = 1.0f;
- power->SetEnergy(energy);
- }
- }
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoPara::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == APAP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoPara::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoParaPhase)OpInt(line, "aPhase", APAP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autopara.h" + + +#include "common/iman.h" +#include "math/geometry.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" + + + + +// Object's constructor. + +CAutoPara::CAutoPara(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + m_channelSound = -1; + Init(); +} + +// Object's destructor. + +CAutoPara::~CAutoPara() +{ +} + + +// Destroys the object. + +void CAutoPara::DeleteObject(bool bAll) +{ + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoPara::Init() +{ + Math::Matrix* mat; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + mat = m_object->RetWorldMatrix(0); + m_pos = Math::Transform(*mat, Math::Vector(22.0f, 4.0f, 0.0f)); + + m_phase = APAP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + CAuto::Init(); +} + + +// Reception of lightning. + +void CAutoPara::StartBlitz() +{ + m_phase = APAP_BLITZ; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; +} + + +// Management of an event. + +bool CAutoPara::EventProcess(const Event &event) +{ + Math::Vector pos, speed; + Math::Point dim; + int i; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + } + return true; + } + + EventProgress(event.rTime); + + if ( m_phase == APAP_BLITZ ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*m_progress*40.0f; + pos.z += (Math::Rand()-0.5f)*m_progress*40.0f; + pos.y += 50.0f-m_progress*50.0f; + speed.x = (Math::Rand()-0.5f)*20.0f; + speed.z = (Math::Rand()-0.5f)*20.0f; + speed.y = 5.0f+Math::Rand()*5.0f; + dim.x = 2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 20.0f, 0.5f); + } + } + } + else + { + m_phase = APAP_CHARGE; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_phase == APAP_CHARGE ) + { + if ( m_progress < 1.0f ) + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<2 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.y += 16.0f; + speed.x = (Math::Rand()-0.5f)*10.0f; + speed.z = (Math::Rand()-0.5f)*10.0f; + speed.y = -Math::Rand()*30.0f; + dim.x = 1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + } + } + + ChargeObject(event.rTime); + } + else + { + m_phase = APAP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoPara::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 113, EVENT_OBJECT_TYPE); + + pos.x = ox+sx*10.2f; + pos.y = oy+sy*0.5f; + ddim.x = 33.0f/640.0f; + ddim.y = 33.0f/480.0f; + pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoPara::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + return ERR_OK; +} + + +// Load all objects under the lightning rod. + +void CAutoPara::ChargeObject(float rTime) +{ + CObject* pObj; + CObject* power; + Math::Vector sPos, oPos; + float dist, energy; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, sPos); + if ( dist > 20.0f ) continue; + + if ( pObj->RetTruck() == 0 && pObj->RetType() == OBJECT_POWER ) + { + energy = pObj->RetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + pObj->SetEnergy(energy); + } + + power = pObj->RetPower(); + if ( power != 0 && power->RetType() == OBJECT_POWER ) + { + energy = power->RetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + power->SetEnergy(energy); + } + + power = pObj->RetFret(); + if ( power != 0 && power->RetType() == OBJECT_POWER ) + { + energy = power->RetEnergy(); + energy += rTime/2.0f; + if ( energy > 1.0f ) energy = 1.0f; + power->SetEnergy(energy); + } + } +} + + +// Saves all parameters of the controller. + +bool CAutoPara::Write(char *line) +{ + char name[100]; + + if ( m_phase == APAP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoPara::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoParaPhase)OpInt(line, "aPhase", APAP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autopara.h b/src/object/auto/autopara.h index e28aa47..b230fd2 100644 --- a/src/object/auto/autopara.h +++ b/src/object/auto/autopara.h @@ -1,65 +1,65 @@ -// * 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/.
-
-// autopara.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoParaPhase
-{
- APAP_WAIT = 1,
- APAP_BLITZ = 2,
- APAP_CHARGE = 3,
-};
-
-
-
-class CAutoPara : public CAuto
-{
-public:
- CAutoPara(CInstanceManager* iMan, CObject* object);
- ~CAutoPara();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
- void StartBlitz();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- void ChargeObject(float rTime);
-
-protected:
- AutoParaPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- Math::Vector m_pos;
- int m_channelSound;
-};
-
+// * 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/. + +// autopara.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoParaPhase +{ + APAP_WAIT = 1, + APAP_BLITZ = 2, + APAP_CHARGE = 3, +}; + + + +class CAutoPara : public CAuto +{ +public: + CAutoPara(CInstanceManager* iMan, CObject* object); + ~CAutoPara(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + void StartBlitz(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + void ChargeObject(float rTime); + +protected: + AutoParaPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + Math::Vector m_pos; + int m_channelSound; +}; + diff --git a/src/object/auto/autoportico.cpp b/src/object/auto/autoportico.cpp index ee3376f..5665556 100644 --- a/src/object/auto/autoportico.cpp +++ b/src/object/auto/autoportico.cpp @@ -1,425 +1,425 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoportico.h"
-
-
-#include "object/robotmain.h"
-
-
-
-
-const int PARAM_DEPOSE = 2; // run=2 -> deposits the spaceship
-
-const float PORTICO_POSa = 75.0f;
-const float PORTICO_POSb = 65.0f;
-const float PORTICO_ANGLE1a = ( 25.0f*Math::PI/180.0f);
-const float PORTICO_ANGLE1b = ( 70.0f*Math::PI/180.0f);
-const float PORTICO_ANGLE2a = (-37.5f*Math::PI/180.0f);
-const float PORTICO_ANGLE2b = (-62.5f*Math::PI/180.0f);
-const float PORTICO_ANGLE3a = (-77.5f*Math::PI/180.0f);
-const float PORTICO_ANGLE3b = (-30.0f*Math::PI/180.0f);
-
-const float PORTICO_TIME_MOVE = 16.0f;
-const float PORTICO_TIME_DOWN = 4.0f;
-const float PORTICO_TIME_OPEN = 12.0f;
-
-
-
-
-// Si progress=0, return a.
-// Si progress=1, return b.
-
-float Progress(float a, float b, float progress)
-{
- return a+(b-a)*progress;
-}
-
-
-
-// Object's constructor.
-
-CAutoPortico::CAutoPortico(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
- m_phase = APOP_WAIT;
- m_soundChannel = -1;
-}
-
-// Object's destructor.
-
-CAutoPortico::~CAutoPortico()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoPortico::DeleteObject(bool bAll)
-{
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoPortico::Init()
-{
- m_time = 0.0f;
- m_lastParticule = 0.0f;
- m_posTrack = 0.0f;
-
- m_phase = APOP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- m_cameraProgress = 0.0f;
- m_cameraSpeed = 1.0f/(PORTICO_TIME_MOVE-2.0f);
-}
-
-
-// Starts the object.
-
-void CAutoPortico::Start(int param)
-{
- Math::Vector pos;
-
- pos = m_object->RetPosition(0);
- m_finalPos = pos;
- pos.z += PORTICO_TIME_MOVE*5.0f; // back to start
- m_object->SetPosition(0, pos);
- m_finalPos.z += PORTICO_TIME_OPEN*5.3f;
-
- m_object->SetPosition(1, Math::Vector(0.0f, PORTICO_POSa, 0.0f));
- m_object->SetAngleY(2, PORTICO_ANGLE1a);
- m_object->SetAngleY(3, PORTICO_ANGLE2a);
- m_object->SetAngleY(4, PORTICO_ANGLE3a);
- m_object->SetAngleY(5, -PORTICO_ANGLE1a);
- m_object->SetAngleY(6, -PORTICO_ANGLE2a);
- m_object->SetAngleY(7, -PORTICO_ANGLE3a);
-
- m_phase = APOP_START;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- m_param = param;
-}
-
-
-// Management of an event.
-
-bool CAutoPortico::EventProcess(const Event &event)
-{
- CObject* pObj;
- Math::Vector pos;
- float angle;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
-
- if ( m_phase == APOP_START )
- {
- if ( m_param == PARAM_DEPOSE ) // deposits the ship?
- {
- m_startPos = m_object->RetPosition(0);
-
- m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_MOVE-0.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP);
-
- m_phase = APOP_MOVE;
- m_progress = 0.0f;
- m_speed = 1.0f/PORTICO_TIME_MOVE;
-
- m_main->SetMovieLock(true); // blocks everything until the end of the landing
-
- m_camera->SetType(CAMERA_SCRIPT);
-
- pos = m_startPos;
- pos.x += -100.0f;
- pos.y += 9.0f;
- pos.z += -200.0f;
- m_camera->SetScriptEye(pos);
-
- pos = m_object->RetPosition(0);
- pos.x += 0.0f;
- pos.y += 10.0f;
- pos.z += -40.0f;
- m_camera->SetScriptLookat(pos);
-
- m_camera->FixCamera();
- }
- }
-
- angle = -m_time*1.0f;
- m_object->SetAngleY(8, angle); // rotates the radar right
- angle = sinf(m_time*4.0f)*0.3f;
- m_object->SetAngleX(9, angle);
-
- angle = -m_time*1.0f+Math::PI/2.3f;
- m_object->SetAngleY(10, angle); // turns the left side radar
- angle = sinf(m_time*4.0f)*0.3f;
- m_object->SetAngleX(11, angle);
-
- if ( event.event != EVENT_FRAME ) return true;
- if ( m_phase == APOP_WAIT ) return true;
-
- m_progress += event.rTime*m_speed;
- m_cameraProgress += event.rTime*m_cameraSpeed;
-
- if ( m_phase == APOP_MOVE )
- {
- if ( m_progress < 1.0f )
- {
- pos = m_object->RetPosition(0);
- pos.z -= event.rTime*5.0f; // advance
- m_object->SetPosition(0, pos);
-
- m_posTrack += event.rTime*0.5f;
- UpdateTrackMapping(m_posTrack, m_posTrack);
- }
- else
- {
- m_phase = APOP_WAIT1;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == APOP_WAIT1 )
- {
- if ( m_progress >= 1.0f )
- {
- m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.5f, 1.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.6f, PORTICO_TIME_DOWN-1.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP);
-
- m_phase = APOP_DOWN;
- m_progress = 0.0f;
- m_speed = 1.0f/PORTICO_TIME_DOWN;
- }
- }
-
- if ( m_phase == APOP_DOWN )
- {
- if ( m_progress < 1.0f )
- {
- pos.x = 0.0f;
- pos.y = Progress(PORTICO_POSa, PORTICO_POSb, m_progress);
- pos.z = 0.0f;
- m_object->SetPosition(1, pos);
- }
- else
- {
- pos.x = 0.0f;
- pos.y = PORTICO_POSb;
- pos.z = 0.0f;
- m_object->SetPosition(1, pos);
-
- m_phase = APOP_WAIT2;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == APOP_WAIT2 )
- {
- if ( m_progress >= 1.0f )
- {
- m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.5f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, 0.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, PORTICO_TIME_OPEN/2.0f-0.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP);
-
- m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, true);
- m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_OPEN-0.5f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP);
-
- m_phase = APOP_OPEN;
- m_progress = 0.0f;
- m_speed = 1.0f/PORTICO_TIME_OPEN;
- }
- }
-
- if ( m_phase == APOP_OPEN )
- {
- if ( m_progress < 1.0f )
- {
- pos = m_object->RetPosition(0);
- pos.z += event.rTime*5.3f; // back
- m_object->SetPosition(0, pos);
-
- m_posTrack -= event.rTime*1.0f;
- UpdateTrackMapping(m_posTrack, m_posTrack);
-
- if ( m_progress < 0.5f )
- {
- angle = Progress(PORTICO_ANGLE1a, PORTICO_ANGLE1b, m_progress/0.5f);
- m_object->SetAngleY(2, angle);
- m_object->SetAngleY(5, -angle);
- angle = Progress(PORTICO_ANGLE2a, PORTICO_ANGLE2b, m_progress/0.5f);
- m_object->SetAngleY(3, angle);
- m_object->SetAngleY(6, -angle);
- angle = Progress(PORTICO_ANGLE3a, PORTICO_ANGLE3b, m_progress/0.5f);
- m_object->SetAngleY(4, angle);
- m_object->SetAngleY(7, -angle);
- }
- else
- {
- m_object->SetAngleY(2, PORTICO_ANGLE1b);
- m_object->SetAngleY(3, PORTICO_ANGLE2b);
- m_object->SetAngleY(4, PORTICO_ANGLE3b);
- m_object->SetAngleY(5, -PORTICO_ANGLE1b);
- m_object->SetAngleY(6, -PORTICO_ANGLE2b);
- m_object->SetAngleY(7, -PORTICO_ANGLE3b);
- }
- }
- else
- {
- m_main->SetMovieLock(false); // you can play!
-
- pObj = m_main->SearchHuman();
- m_main->SelectObject(pObj);
- m_camera->SetObject(pObj);
- m_camera->SetType(CAMERA_BACK);
-
- m_phase = APOP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
- }
- }
-
- if ( m_soundChannel != -1 )
- {
-//? m_sound->Position(m_soundChannel, m_object->RetPosition(0));
- pos = m_engine->RetEyePt();
- m_sound->Position(m_soundChannel, pos);
- }
-
- if ( m_cameraProgress < 1.0f )
- {
- if ( m_cameraProgress < 0.5f )
- {
- }
- else
- {
- pos = m_startPos;
- pos.x += -100.0f-(m_cameraProgress-0.5f)*1.0f*120.0f;
- pos.y += 9.0f;
- pos.z += -200.0f+(m_cameraProgress-0.5f)*1.0f*210.0f;
- m_camera->SetScriptEye(pos);
- }
-
- pos = m_object->RetPosition(0);
- pos.x += 0.0f;
- pos.y += 10.0f;
- pos.z += -40.0f;
- m_camera->SetScriptLookat(pos);
- }
-
- return true;
-}
-
-// Stops the controller.
-
-bool CAutoPortico::Abort()
-{
- CObject* pObj;
-
- m_object->SetPosition(0, m_finalPos);
- m_object->SetPosition(1, Math::Vector(0.0f, PORTICO_POSb, 0.0f));
- m_object->SetAngleY(2, PORTICO_ANGLE1b);
- m_object->SetAngleY(3, PORTICO_ANGLE2b);
- m_object->SetAngleY(4, PORTICO_ANGLE3b);
- m_object->SetAngleY(5, -PORTICO_ANGLE1b);
- m_object->SetAngleY(6, -PORTICO_ANGLE2b);
- m_object->SetAngleY(7, -PORTICO_ANGLE3b);
-
- m_main->SetMovieLock(false); // you can play!
-
- pObj = m_main->SearchHuman();
- m_main->SelectObject(pObj);
- m_camera->SetObject(pObj);
- m_camera->SetType(CAMERA_BACK);
-
- if ( m_soundChannel != -1 )
- {
- m_sound->FlushEnvelope(m_soundChannel);
- m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_soundChannel = -1;
- }
-
- m_phase = APOP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/2.0f;
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoPortico::RetError()
-{
- return ERR_OK;
-}
-
-
-// Updates the mapping of the texture of the caterpillars.
-
-void CAutoPortico::UpdateTrackMapping(float left, float right)
-{
- D3DMATERIAL7 mat;
- float limit[2];
- int rank;
-
- ZeroMemory( &mat, sizeof(D3DMATERIAL7) );
- mat.diffuse.r = 1.0f;
- mat.diffuse.g = 1.0f;
- mat.diffuse.b = 1.0f; // blank
- mat.ambient.r = 0.5f;
- mat.ambient.g = 0.5f;
- mat.ambient.b = 0.5f;
-
- rank = m_object->RetObjectRank(0);
-
- limit[0] = 0.0f;
- limit[1] = 1000000.0f;
-
- m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART1, "lemt.tga", "",
- limit[0], limit[1], D3DMAPPINGX,
- right, 8.0f, 8.0f, 192.0f, 256.0f);
-
- m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART2, "lemt.tga", "",
- limit[0], limit[1], D3DMAPPINGX,
- left, 8.0f, 8.0f, 192.0f, 256.0f);
-}
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autoportico.h" + + +#include "object/robotmain.h" + + + + +const int PARAM_DEPOSE = 2; // run=2 -> deposits the spaceship + +const float PORTICO_POSa = 75.0f; +const float PORTICO_POSb = 65.0f; +const float PORTICO_ANGLE1a = ( 25.0f*Math::PI/180.0f); +const float PORTICO_ANGLE1b = ( 70.0f*Math::PI/180.0f); +const float PORTICO_ANGLE2a = (-37.5f*Math::PI/180.0f); +const float PORTICO_ANGLE2b = (-62.5f*Math::PI/180.0f); +const float PORTICO_ANGLE3a = (-77.5f*Math::PI/180.0f); +const float PORTICO_ANGLE3b = (-30.0f*Math::PI/180.0f); + +const float PORTICO_TIME_MOVE = 16.0f; +const float PORTICO_TIME_DOWN = 4.0f; +const float PORTICO_TIME_OPEN = 12.0f; + + + + +// Si progress=0, return a. +// Si progress=1, return b. + +float Progress(float a, float b, float progress) +{ + return a+(b-a)*progress; +} + + + +// Object's constructor. + +CAutoPortico::CAutoPortico(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); + m_phase = APOP_WAIT; + m_soundChannel = -1; +} + +// Object's destructor. + +CAutoPortico::~CAutoPortico() +{ +} + + +// Destroys the object. + +void CAutoPortico::DeleteObject(bool bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoPortico::Init() +{ + m_time = 0.0f; + m_lastParticule = 0.0f; + m_posTrack = 0.0f; + + m_phase = APOP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + m_cameraProgress = 0.0f; + m_cameraSpeed = 1.0f/(PORTICO_TIME_MOVE-2.0f); +} + + +// Starts the object. + +void CAutoPortico::Start(int param) +{ + Math::Vector pos; + + pos = m_object->RetPosition(0); + m_finalPos = pos; + pos.z += PORTICO_TIME_MOVE*5.0f; // back to start + m_object->SetPosition(0, pos); + m_finalPos.z += PORTICO_TIME_OPEN*5.3f; + + m_object->SetPosition(1, Math::Vector(0.0f, PORTICO_POSa, 0.0f)); + m_object->SetAngleY(2, PORTICO_ANGLE1a); + m_object->SetAngleY(3, PORTICO_ANGLE2a); + m_object->SetAngleY(4, PORTICO_ANGLE3a); + m_object->SetAngleY(5, -PORTICO_ANGLE1a); + m_object->SetAngleY(6, -PORTICO_ANGLE2a); + m_object->SetAngleY(7, -PORTICO_ANGLE3a); + + m_phase = APOP_START; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_param = param; +} + + +// Management of an event. + +bool CAutoPortico::EventProcess(const Event &event) +{ + CObject* pObj; + Math::Vector pos; + float angle; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + + if ( m_phase == APOP_START ) + { + if ( m_param == PARAM_DEPOSE ) // deposits the ship? + { + m_startPos = m_object->RetPosition(0); + + m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, true); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_MOVE-0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); + + m_phase = APOP_MOVE; + m_progress = 0.0f; + m_speed = 1.0f/PORTICO_TIME_MOVE; + + m_main->SetMovieLock(true); // blocks everything until the end of the landing + + m_camera->SetType(CAMERA_SCRIPT); + + pos = m_startPos; + pos.x += -100.0f; + pos.y += 9.0f; + pos.z += -200.0f; + m_camera->SetScriptEye(pos); + + pos = m_object->RetPosition(0); + pos.x += 0.0f; + pos.y += 10.0f; + pos.z += -40.0f; + m_camera->SetScriptLookat(pos); + + m_camera->FixCamera(); + } + } + + angle = -m_time*1.0f; + m_object->SetAngleY(8, angle); // rotates the radar right + angle = sinf(m_time*4.0f)*0.3f; + m_object->SetAngleX(9, angle); + + angle = -m_time*1.0f+Math::PI/2.3f; + m_object->SetAngleY(10, angle); // turns the left side radar + angle = sinf(m_time*4.0f)*0.3f; + m_object->SetAngleX(11, angle); + + if ( event.event != EVENT_FRAME ) return true; + if ( m_phase == APOP_WAIT ) return true; + + m_progress += event.rTime*m_speed; + m_cameraProgress += event.rTime*m_cameraSpeed; + + if ( m_phase == APOP_MOVE ) + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.z -= event.rTime*5.0f; // advance + m_object->SetPosition(0, pos); + + m_posTrack += event.rTime*0.5f; + UpdateTrackMapping(m_posTrack, m_posTrack); + } + else + { + m_phase = APOP_WAIT1; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == APOP_WAIT1 ) + { + if ( m_progress >= 1.0f ) + { + m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, true); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.5f, 1.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.6f, PORTICO_TIME_DOWN-1.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); + + m_phase = APOP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/PORTICO_TIME_DOWN; + } + } + + if ( m_phase == APOP_DOWN ) + { + if ( m_progress < 1.0f ) + { + pos.x = 0.0f; + pos.y = Progress(PORTICO_POSa, PORTICO_POSb, m_progress); + pos.z = 0.0f; + m_object->SetPosition(1, pos); + } + else + { + pos.x = 0.0f; + pos.y = PORTICO_POSb; + pos.z = 0.0f; + m_object->SetPosition(1, pos); + + m_phase = APOP_WAIT2; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == APOP_WAIT2 ) + { + if ( m_progress >= 1.0f ) + { + m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.5f, true); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, PORTICO_TIME_OPEN/2.0f-0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); + + m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, true); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_OPEN-0.5f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); + + m_phase = APOP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/PORTICO_TIME_OPEN; + } + } + + if ( m_phase == APOP_OPEN ) + { + if ( m_progress < 1.0f ) + { + pos = m_object->RetPosition(0); + pos.z += event.rTime*5.3f; // back + m_object->SetPosition(0, pos); + + m_posTrack -= event.rTime*1.0f; + UpdateTrackMapping(m_posTrack, m_posTrack); + + if ( m_progress < 0.5f ) + { + angle = Progress(PORTICO_ANGLE1a, PORTICO_ANGLE1b, m_progress/0.5f); + m_object->SetAngleY(2, angle); + m_object->SetAngleY(5, -angle); + angle = Progress(PORTICO_ANGLE2a, PORTICO_ANGLE2b, m_progress/0.5f); + m_object->SetAngleY(3, angle); + m_object->SetAngleY(6, -angle); + angle = Progress(PORTICO_ANGLE3a, PORTICO_ANGLE3b, m_progress/0.5f); + m_object->SetAngleY(4, angle); + m_object->SetAngleY(7, -angle); + } + else + { + m_object->SetAngleY(2, PORTICO_ANGLE1b); + m_object->SetAngleY(3, PORTICO_ANGLE2b); + m_object->SetAngleY(4, PORTICO_ANGLE3b); + m_object->SetAngleY(5, -PORTICO_ANGLE1b); + m_object->SetAngleY(6, -PORTICO_ANGLE2b); + m_object->SetAngleY(7, -PORTICO_ANGLE3b); + } + } + else + { + m_main->SetMovieLock(false); // you can play! + + pObj = m_main->SearchHuman(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + m_camera->SetType(CAMERA_BACK); + + m_phase = APOP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + } + + if ( m_soundChannel != -1 ) + { +//? m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + pos = m_engine->RetEyePt(); + m_sound->Position(m_soundChannel, pos); + } + + if ( m_cameraProgress < 1.0f ) + { + if ( m_cameraProgress < 0.5f ) + { + } + else + { + pos = m_startPos; + pos.x += -100.0f-(m_cameraProgress-0.5f)*1.0f*120.0f; + pos.y += 9.0f; + pos.z += -200.0f+(m_cameraProgress-0.5f)*1.0f*210.0f; + m_camera->SetScriptEye(pos); + } + + pos = m_object->RetPosition(0); + pos.x += 0.0f; + pos.y += 10.0f; + pos.z += -40.0f; + m_camera->SetScriptLookat(pos); + } + + return true; +} + +// Stops the controller. + +bool CAutoPortico::Abort() +{ + CObject* pObj; + + m_object->SetPosition(0, m_finalPos); + m_object->SetPosition(1, Math::Vector(0.0f, PORTICO_POSb, 0.0f)); + m_object->SetAngleY(2, PORTICO_ANGLE1b); + m_object->SetAngleY(3, PORTICO_ANGLE2b); + m_object->SetAngleY(4, PORTICO_ANGLE3b); + m_object->SetAngleY(5, -PORTICO_ANGLE1b); + m_object->SetAngleY(6, -PORTICO_ANGLE2b); + m_object->SetAngleY(7, -PORTICO_ANGLE3b); + + m_main->SetMovieLock(false); // you can play! + + pObj = m_main->SearchHuman(); + m_main->SelectObject(pObj); + m_camera->SetObject(pObj); + m_camera->SetType(CAMERA_BACK); + + if ( m_soundChannel != -1 ) + { + m_sound->FlushEnvelope(m_soundChannel); + m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_soundChannel = -1; + } + + m_phase = APOP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoPortico::RetError() +{ + return ERR_OK; +} + + +// Updates the mapping of the texture of the caterpillars. + +void CAutoPortico::UpdateTrackMapping(float left, float right) +{ + D3DMATERIAL7 mat; + float limit[2]; + int rank; + + ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); + mat.diffuse.r = 1.0f; + mat.diffuse.g = 1.0f; + mat.diffuse.b = 1.0f; // blank + mat.ambient.r = 0.5f; + mat.ambient.g = 0.5f; + mat.ambient.b = 0.5f; + + rank = m_object->RetObjectRank(0); + + limit[0] = 0.0f; + limit[1] = 1000000.0f; + + m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART1, "lemt.tga", "", + limit[0], limit[1], D3DMAPPINGX, + right, 8.0f, 8.0f, 192.0f, 256.0f); + + m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART2, "lemt.tga", "", + limit[0], limit[1], D3DMAPPINGX, + left, 8.0f, 8.0f, 192.0f, 256.0f); +} + diff --git a/src/object/auto/autoportico.h b/src/object/auto/autoportico.h index 566c358..f2cd6d1 100644 --- a/src/object/auto/autoportico.h +++ b/src/object/auto/autoportico.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/.
-
-// autoportico.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoPorticoPhase
-{
- APOP_WAIT = 1, // waits
- APOP_START = 2, // start of the action
- APOP_MOVE = 3, // advance
- APOP_WAIT1 = 4, // waits
- APOP_DOWN = 5, // down
- APOP_WAIT2 = 6, // waits
- APOP_OPEN = 7, // opens
-};
-
-
-
-class CAutoPortico : public CAuto
-{
-public:
- CAutoPortico(CInstanceManager* iMan, CObject* object);
- ~CAutoPortico();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- void Start(int param);
- bool EventProcess(const Event &event);
- bool Abort();
- Error RetError();
-
-protected:
- void UpdateTrackMapping(float left, float right);
-
-protected:
- AutoPorticoPhase m_phase;
- float m_progress;
- float m_speed;
- float m_cameraProgress;
- float m_cameraSpeed;
- float m_lastParticule;
- Math::Vector m_finalPos;
- Math::Vector m_startPos;
- float m_posTrack;
- int m_param;
- int m_soundChannel;
-};
-
+// * 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/. + +// autoportico.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoPorticoPhase +{ + APOP_WAIT = 1, // waits + APOP_START = 2, // start of the action + APOP_MOVE = 3, // advance + APOP_WAIT1 = 4, // waits + APOP_DOWN = 5, // down + APOP_WAIT2 = 6, // waits + APOP_OPEN = 7, // opens +}; + + + +class CAutoPortico : public CAuto +{ +public: + CAutoPortico(CInstanceManager* iMan, CObject* object); + ~CAutoPortico(); + + void DeleteObject(bool bAll=false); + + void Init(); + void Start(int param); + bool EventProcess(const Event &event); + bool Abort(); + Error RetError(); + +protected: + void UpdateTrackMapping(float left, float right); + +protected: + AutoPorticoPhase m_phase; + float m_progress; + float m_speed; + float m_cameraProgress; + float m_cameraSpeed; + float m_lastParticule; + Math::Vector m_finalPos; + Math::Vector m_startPos; + float m_posTrack; + int m_param; + int m_soundChannel; +}; + diff --git a/src/object/auto/autoradar.cpp b/src/object/auto/autoradar.cpp index b8bee44..1cb20d6 100644 --- a/src/object/auto/autoradar.cpp +++ b/src/object/auto/autoradar.cpp @@ -1,306 +1,306 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoradar.h"
-
-#include "common/iman.h"
-#include "math/geometry.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-#include "ui/gauge.h"
-
-
-// Object's constructor.
-
-CAutoRadar::CAutoRadar(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
- m_phase = ARAP_WAIT;
- m_totalDetect = 0;
-}
-
-// Object's destructor.
-
-CAutoRadar::~CAutoRadar()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoRadar::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoRadar::Init()
-{
- m_phase = ARAP_SEARCH;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
-
- m_aTime = 0.0f;
- m_time = 0.0f;
- m_timeVirus = 0.0f;
-}
-
-
-// Management of an event.
-
-bool CAutoRadar::EventProcess(const Event &event)
-{
- Math::Vector pos, ePos;
- float speed, angle, prog, freq, ampl;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
- if ( m_phase == ARAP_WAIT ) return true;
-
- m_progress += event.rTime*m_speed;
- m_aTime += event.rTime;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
-
- angle = m_object->RetAngleY(1);
- angle += (Math::Rand()-0.2f)*0.5f;
- m_object->SetAngleY(1, angle);
-
- angle = m_object->RetAngleY(2);
- angle += (Math::Rand()-0.8f)*1.0f;
- m_object->SetAngleY(2, angle);
-
- m_object->SetAngleX(3, (Math::Rand()-0.5f)*0.3f);
-
- m_totalDetect = (int)(Math::Rand()*10.0f);
- UpdateInterface();
- }
- return true;
- }
-
- if ( m_phase == ARAP_SEARCH )
- {
- if ( m_progress < 1.0f )
- {
- speed = Math::Min(10.0f, m_progress*50.0f);
- angle = m_object->RetAngleY(1);
- angle += event.rTime*speed;
- m_object->SetAngleY(1, angle);
- }
- else
- {
- if ( !SearchEnemy(ePos) )
- {
- m_phase = ARAP_SEARCH;
- m_progress = 10.0f/50.0f; // full speed immediately
- m_speed = 1.0f/3.0f;
- }
- else
- {
- pos = m_object->RetPosition(0);
- m_start = m_object->RetAngleY(1);
- m_angle = m_start-Math::NormAngle(m_start)+Math::PI*2.0f;
- m_angle += Math::RotateAngle(pos.x-ePos.x, ePos.z-pos.z);
- m_angle += Math::PI-m_object->RetAngleY(0);
-
- m_phase = ARAP_SHOW;
- m_progress = 0.0f;
- m_speed = 1.0f/(fabs(m_angle-m_start)/10.0f);
- }
- }
- }
-
- if ( m_phase == ARAP_SHOW )
- {
- if ( m_progress < 1.0f )
- {
- angle = m_start + (m_angle-m_start)*m_progress;
- m_object->SetAngleY(1, angle);
- }
- else
- {
- m_sound->Play(SOUND_RADAR, m_object->RetPosition(0));
-
- m_phase = ARAP_SINUS;
- m_progress = 0.0f;
- m_speed = 1.0f/4.0f;
- m_time = 0.0f;
- }
- }
-
- if ( m_phase == ARAP_SINUS )
- {
- if ( m_progress < 1.0f )
- {
- prog = Math::Min(1.0f, m_progress*2.0f);
- freq = 16.0f*(prog+1.0f);
- ampl = 0.2f-prog*0.2f;
- angle = m_angle + sinf(m_time*freq)*ampl;
- m_object->SetAngleY(1, angle);
- }
- else
- {
- m_phase = ARAP_SEARCH;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
- }
-
- angle = -m_aTime*2.0f;
- m_object->SetAngleY(2, angle);
-
- angle = sinf(m_aTime*4.0f)*0.3f;
- m_object->SetAngleX(3, angle);
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoRadar::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- return ERR_OK;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoRadar::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, dim, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*7.0f;
- pos.y = oy+sy*0.6f;
- dim.x = 160.0f/640.0f;
- dim.y = 26.0f/480.0f;
- pw->CreateGauge(pos, dim, 1, EVENT_OBJECT_GRADAR);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 105, EVENT_OBJECT_TYPE);
-
- UpdateInterface();
- return true;
-}
-
-// Updates the status of all interface buttons.
-
-void CAutoRadar::UpdateInterface()
-{
- CWindow* pw;
- CGauge* pg;
- float level;
-
- if ( !m_object->RetSelect() ) return;
-
- CAuto::UpdateInterface();
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GRADAR);
- if ( pg != 0 )
- {
- level = (float)m_totalDetect*(1.0f/8.0f);
- if ( level > 1.0f ) level = 1.0f;
- pg->SetLevel(level);
- }
-}
-
-
-// Seeking the position of an enemy.
-
-bool CAutoRadar::SearchEnemy(Math::Vector &pos)
-{
- CObject* pObj;
- CObject* pBest = 0;
- Math::Vector iPos, oPos;
- ObjectType oType;
- float distance, min;
- int i;
-
- iPos = m_object->RetPosition(0);
- min = 1000000.0f;
- m_totalDetect = 0;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( !pObj->RetActif() ) continue;
-
- oType = pObj->RetType();
- if ( oType != OBJECT_ANT &&
- oType != OBJECT_SPIDER &&
- oType != OBJECT_BEE &&
- oType != OBJECT_WORM &&
- oType != OBJECT_MOTHER ) continue;
-
- m_totalDetect ++;
-
- oPos = pObj->RetPosition(0);
- distance = Math::Distance(oPos, iPos);
- if ( distance < min )
- {
- min = distance;
- pBest = pObj;
- }
- }
-
- UpdateInterface();
-
- if ( pBest == 0 ) return false;
- pos = pBest->RetPosition(0);
- 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/. + + +#include <stdio.h> + +#include "object/auto/autoradar.h" + +#include "common/iman.h" +#include "math/geometry.h" +#include "ui/interface.h" +#include "ui/window.h" +#include "ui/gauge.h" + + +// Object's constructor. + +CAutoRadar::CAutoRadar(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); + m_phase = ARAP_WAIT; + m_totalDetect = 0; +} + +// Object's destructor. + +CAutoRadar::~CAutoRadar() +{ +} + + +// Destroys the object. + +void CAutoRadar::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoRadar::Init() +{ + m_phase = ARAP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + + m_aTime = 0.0f; + m_time = 0.0f; + m_timeVirus = 0.0f; +} + + +// Management of an event. + +bool CAutoRadar::EventProcess(const Event &event) +{ + Math::Vector pos, ePos; + float speed, angle, prog, freq, ampl; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + if ( m_phase == ARAP_WAIT ) return true; + + m_progress += event.rTime*m_speed; + m_aTime += event.rTime; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + angle = m_object->RetAngleY(1); + angle += (Math::Rand()-0.2f)*0.5f; + m_object->SetAngleY(1, angle); + + angle = m_object->RetAngleY(2); + angle += (Math::Rand()-0.8f)*1.0f; + m_object->SetAngleY(2, angle); + + m_object->SetAngleX(3, (Math::Rand()-0.5f)*0.3f); + + m_totalDetect = (int)(Math::Rand()*10.0f); + UpdateInterface(); + } + return true; + } + + if ( m_phase == ARAP_SEARCH ) + { + if ( m_progress < 1.0f ) + { + speed = Math::Min(10.0f, m_progress*50.0f); + angle = m_object->RetAngleY(1); + angle += event.rTime*speed; + m_object->SetAngleY(1, angle); + } + else + { + if ( !SearchEnemy(ePos) ) + { + m_phase = ARAP_SEARCH; + m_progress = 10.0f/50.0f; // full speed immediately + m_speed = 1.0f/3.0f; + } + else + { + pos = m_object->RetPosition(0); + m_start = m_object->RetAngleY(1); + m_angle = m_start-Math::NormAngle(m_start)+Math::PI*2.0f; + m_angle += Math::RotateAngle(pos.x-ePos.x, ePos.z-pos.z); + m_angle += Math::PI-m_object->RetAngleY(0); + + m_phase = ARAP_SHOW; + m_progress = 0.0f; + m_speed = 1.0f/(fabs(m_angle-m_start)/10.0f); + } + } + } + + if ( m_phase == ARAP_SHOW ) + { + if ( m_progress < 1.0f ) + { + angle = m_start + (m_angle-m_start)*m_progress; + m_object->SetAngleY(1, angle); + } + else + { + m_sound->Play(SOUND_RADAR, m_object->RetPosition(0)); + + m_phase = ARAP_SINUS; + m_progress = 0.0f; + m_speed = 1.0f/4.0f; + m_time = 0.0f; + } + } + + if ( m_phase == ARAP_SINUS ) + { + if ( m_progress < 1.0f ) + { + prog = Math::Min(1.0f, m_progress*2.0f); + freq = 16.0f*(prog+1.0f); + ampl = 0.2f-prog*0.2f; + angle = m_angle + sinf(m_time*freq)*ampl; + m_object->SetAngleY(1, angle); + } + else + { + m_phase = ARAP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + angle = -m_aTime*2.0f; + m_object->SetAngleY(2, angle); + + angle = sinf(m_aTime*4.0f)*0.3f; + m_object->SetAngleX(3, angle); + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoRadar::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +bool CAutoRadar::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.6f; + dim.x = 160.0f/640.0f; + dim.y = 26.0f/480.0f; + pw->CreateGauge(pos, dim, 1, EVENT_OBJECT_GRADAR); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 105, EVENT_OBJECT_TYPE); + + UpdateInterface(); + return true; +} + +// Updates the status of all interface buttons. + +void CAutoRadar::UpdateInterface() +{ + CWindow* pw; + CGauge* pg; + float level; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GRADAR); + if ( pg != 0 ) + { + level = (float)m_totalDetect*(1.0f/8.0f); + if ( level > 1.0f ) level = 1.0f; + pg->SetLevel(level); + } +} + + +// Seeking the position of an enemy. + +bool CAutoRadar::SearchEnemy(Math::Vector &pos) +{ + CObject* pObj; + CObject* pBest = 0; + Math::Vector iPos, oPos; + ObjectType oType; + float distance, min; + int i; + + iPos = m_object->RetPosition(0); + min = 1000000.0f; + m_totalDetect = 0; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetActif() ) continue; + + oType = pObj->RetType(); + if ( oType != OBJECT_ANT && + oType != OBJECT_SPIDER && + oType != OBJECT_BEE && + oType != OBJECT_WORM && + oType != OBJECT_MOTHER ) continue; + + m_totalDetect ++; + + oPos = pObj->RetPosition(0); + distance = Math::Distance(oPos, iPos); + if ( distance < min ) + { + min = distance; + pBest = pObj; + } + } + + UpdateInterface(); + + if ( pBest == 0 ) return false; + pos = pBest->RetPosition(0); + return true; +} + + diff --git a/src/object/auto/autoradar.h b/src/object/auto/autoradar.h index 5a5020b..8b38ff9 100644 --- a/src/object/auto/autoradar.h +++ b/src/object/auto/autoradar.h @@ -1,64 +1,64 @@ -// * 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/.
-
-// autoradar.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoRadarPhase
-{
- ARAP_WAIT = 1, // waiting
- ARAP_SEARCH = 2, // seeking
- ARAP_SHOW = 3, // watching
- ARAP_SINUS = 4, // oscillates
-};
-
-
-
-class CAutoRadar : public CAuto
-{
-public:
- CAutoRadar(CInstanceManager* iMan, CObject* object);
- ~CAutoRadar();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- bool CreateInterface(bool bSelect);
- Error RetError();
-
-protected:
- void UpdateInterface();
- bool SearchEnemy(Math::Vector &pos);
-
-protected:
- AutoRadarPhase m_phase;
- float m_progress;
- float m_speed;
- float m_aTime;
- float m_timeVirus;
- float m_lastParticule;
- float m_angle;
- float m_start;
- int m_totalDetect;
-};
-
+// * 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/. + +// autoradar.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoRadarPhase +{ + ARAP_WAIT = 1, // waiting + ARAP_SEARCH = 2, // seeking + ARAP_SHOW = 3, // watching + ARAP_SINUS = 4, // oscillates +}; + + + +class CAutoRadar : public CAuto +{ +public: + CAutoRadar(CInstanceManager* iMan, CObject* object); + ~CAutoRadar(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + bool CreateInterface(bool bSelect); + Error RetError(); + +protected: + void UpdateInterface(); + bool SearchEnemy(Math::Vector &pos); + +protected: + AutoRadarPhase m_phase; + float m_progress; + float m_speed; + float m_aTime; + float m_timeVirus; + float m_lastParticule; + float m_angle; + float m_start; + int m_totalDetect; +}; + diff --git a/src/object/auto/autorepair.cpp b/src/object/auto/autorepair.cpp index b56f771..ad5deee 100644 --- a/src/object/auto/autorepair.cpp +++ b/src/object/auto/autorepair.cpp @@ -1,339 +1,339 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autorepair.h"
-
-#include "common/iman.h"
-#include "physics/physics.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-
-
-// Object's constructor.
-
-CAutoRepair::CAutoRepair(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
- m_phase = ARP_WAIT; // paused until the first Init ()
-}
-
-// Object's destructor.
-
-CAutoRepair::~CAutoRepair()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoRepair::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoRepair::Init()
-{
- m_phase = ARP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoRepair::EventProcess(const Event &event)
-{
- CObject* vehicule;
- Math::Vector pos, speed;
- Math::Point dim;
- float angle, shield;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
- }
- return true;
- }
-
- if ( m_phase == ARP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- if ( SearchVehicle() == 0 )
- {
- m_phase = ARP_WAIT; // still waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- else
- {
- m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f);
-
- m_phase = ARP_DOWN;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
- }
- }
-
- if ( m_phase == ARP_DOWN )
- {
- if ( m_progress < 1.0f )
- {
- angle = -m_progress*(Math::PI/2.0f)+Math::PI/2.0f;
- m_object->SetAngleZ(1, angle);
- }
- else
- {
- m_object->SetAngleZ(1, 0.0f);
- m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0));
-
- m_phase = ARP_REPAIR;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ARP_REPAIR )
- {
- vehicule = SearchVehicle();
- if ( m_progress < 1.0f ||
- (vehicule != 0 && vehicule->RetShield() < 1.0f) )
- {
- if ( vehicule != 0 )
- {
- shield = vehicule->RetShield();
- shield += event.rTime*0.2f;
- if ( shield > 1.0f ) shield = 1.0f;
- vehicule->SetShield(shield);
- }
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- 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)*12.0f;
- speed.z = (Math::Rand()-0.5f)*12.0f;
- speed.y = Math::Rand()*15.0f;
- dim.x = Math::Rand()*6.0f+4.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f);
- }
- }
- else
- {
- m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f);
-
- m_phase = ARP_UP;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
- }
-
- if ( m_phase == ARP_UP )
- {
- if ( m_progress < 1.0f )
- {
- angle = -(1.0f-m_progress)*(Math::PI/2.0f)+Math::PI/2.0f;
- m_object->SetAngleZ(1, angle);
- }
- else
- {
- m_object->SetAngleZ(1, Math::PI/2.0f);
-
- m_phase = ARP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoRepair::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-
-// Seeking the vehicle on the station.
-
-CObject* CAutoRepair::SearchVehicle()
-{
- CObject* pObj;
- CPhysics* physics;
- Math::Vector sPos, oPos;
- ObjectType type;
- float dist;
- int i;
-
- sPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEtg &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr ) continue;
-
- physics = pObj->RetPhysics();
- if ( physics != 0 && !physics->RetLand() ) continue; // in flight?
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, sPos);
- if ( dist <= 5.0f ) return pObj;
- }
-
- return 0;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoRepair::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- return ERR_OK;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoRepair::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ARP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoRepair::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoRepairPhase)OpInt(line, "aPhase", ARP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autorepair.h" + +#include "common/iman.h" +#include "physics/physics.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" + + +// Object's constructor. + +CAutoRepair::CAutoRepair(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); + m_phase = ARP_WAIT; // paused until the first Init () +} + +// Object's destructor. + +CAutoRepair::~CAutoRepair() +{ +} + + +// Destroys the object. + +void CAutoRepair::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoRepair::Init() +{ + m_phase = ARP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoRepair::EventProcess(const Event &event) +{ + CObject* vehicule; + Math::Vector pos, speed; + Math::Point dim; + float angle, shield; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + } + return true; + } + + if ( m_phase == ARP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + if ( SearchVehicle() == 0 ) + { + m_phase = ARP_WAIT; // still waiting ... + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + else + { + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + + m_phase = ARP_DOWN; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + } + + if ( m_phase == ARP_DOWN ) + { + if ( m_progress < 1.0f ) + { + angle = -m_progress*(Math::PI/2.0f)+Math::PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, 0.0f); + m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); + + m_phase = ARP_REPAIR; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ARP_REPAIR ) + { + vehicule = SearchVehicle(); + if ( m_progress < 1.0f || + (vehicule != 0 && vehicule->RetShield() < 1.0f) ) + { + if ( vehicule != 0 ) + { + shield = vehicule->RetShield(); + shield += event.rTime*0.2f; + if ( shield > 1.0f ) shield = 1.0f; + vehicule->SetShield(shield); + } + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + 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)*12.0f; + speed.z = (Math::Rand()-0.5f)*12.0f; + speed.y = Math::Rand()*15.0f; + dim.x = Math::Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + } + } + else + { + m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + + m_phase = ARP_UP; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + + if ( m_phase == ARP_UP ) + { + if ( m_progress < 1.0f ) + { + angle = -(1.0f-m_progress)*(Math::PI/2.0f)+Math::PI/2.0f; + m_object->SetAngleZ(1, angle); + } + else + { + m_object->SetAngleZ(1, Math::PI/2.0f); + + m_phase = ARP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoRepair::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 106, EVENT_OBJECT_TYPE); + + return true; +} + + +// Seeking the vehicle on the station. + +CObject* CAutoRepair::SearchVehicle() +{ + CObject* pObj; + CPhysics* physics; + Math::Vector sPos, oPos; + ObjectType type; + float dist; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEtg && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr ) continue; + + physics = pObj->RetPhysics(); + if ( physics != 0 && !physics->RetLand() ) continue; // in flight? + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, sPos); + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoRepair::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + + +// Saves all parameters of the controller. + +bool CAutoRepair::Write(char *line) +{ + char name[100]; + + if ( m_phase == ARP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoRepair::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoRepairPhase)OpInt(line, "aPhase", ARP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autorepair.h b/src/object/auto/autorepair.h index 1178529..1279ba3 100644 --- a/src/object/auto/autorepair.h +++ b/src/object/auto/autorepair.h @@ -1,65 +1,65 @@ -// * 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/.
-
-// autorepair.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoRepairPhase
-{
- ARP_WAIT = 1, // expected metal
- ARP_DOWN = 2, // down the cover
- ARP_REPAIR = 3, // repair the vehicle
- ARP_UP = 4, // back cover
-
-};
-
-
-
-class CAutoRepair : public CAuto
-{
-public:
- CAutoRepair(CInstanceManager* iMan, CObject* object);
- ~CAutoRepair();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- CObject* SearchVehicle();
-
-protected:
- AutoRepairPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- 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/. + +// autorepair.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoRepairPhase +{ + ARP_WAIT = 1, // expected metal + ARP_DOWN = 2, // down the cover + ARP_REPAIR = 3, // repair the vehicle + ARP_UP = 4, // back cover + +}; + + + +class CAutoRepair : public CAuto +{ +public: + CAutoRepair(CInstanceManager* iMan, CObject* object); + ~CAutoRepair(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + CObject* SearchVehicle(); + +protected: + AutoRepairPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; +}; + + diff --git a/src/object/auto/autoresearch.cpp b/src/object/auto/autoresearch.cpp index abf228c..bc6dbd0 100644 --- a/src/object/auto/autoresearch.cpp +++ b/src/object/auto/autoresearch.cpp @@ -1,608 +1,608 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoresearch.h"
-
-#include "common/global.h"
-#include "math/geometry.h"
-#include "object/robotmain.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/gauge.h"
-#include "ui/window.h"
-#include "ui/displaytext.h"
-
-
-
-const float SEARCH_TIME = 30.0f; // duration of a research
-
-
-
-// Object's constructor.
-
-CAutoResearch::CAutoResearch(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- int i;
-
- for ( i=0 ; i<6 ; i++ )
- {
- m_partiStop[i] = -1;
- }
- m_channelSound = -1;
-
- Init();
-}
-
-// Object's destructor.
-
-CAutoResearch::~CAutoResearch()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoResearch::DeleteObject(bool bAll)
-{
- if ( m_channelSound != -1 )
- {
- m_sound->FlushEnvelope(m_channelSound);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_channelSound = -1;
- }
-
- FireStopUpdate(0.0f, false);
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoResearch::Init()
-{
- m_phase = ALP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastUpdateTime = 0.0f;
- m_lastParticule = 0.0f;
-}
-
-
-// Management of an event.
-
-bool CAutoResearch::EventProcess(const Event &event)
-{
- CObject* power;
- Math::Vector pos, speed;
- Error message;
- Math::Point dim;
- float angle, time;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
-
- if ( event.event == EVENT_UPDINTERFACE )
- {
- if ( m_object->RetSelect() ) CreateInterface(true);
- }
-
- if ( m_object->RetSelect() && // center selected?
- (event.event == EVENT_OBJECT_RTANK ||
- event.event == EVENT_OBJECT_RFLY ||
- event.event == EVENT_OBJECT_RTHUMP ||
- event.event == EVENT_OBJECT_RCANON ||
- event.event == EVENT_OBJECT_RTOWER ||
- event.event == EVENT_OBJECT_RPHAZER ||
- event.event == EVENT_OBJECT_RSHIELD ||
- event.event == EVENT_OBJECT_RATOMIC ) )
- {
- if ( m_phase != ALP_WAIT )
- {
- return false;
- }
-
- m_research = event.event;
-
- if ( TestResearch(m_research) )
- {
- m_displayText->DisplayError(ERR_RESEARCH_ALREADY, m_object);
- return false;
- }
-
- power = m_object->RetPower();
- if ( power == 0 )
- {
- m_displayText->DisplayError(ERR_RESEARCH_POWER, m_object);
- return false;
- }
- if ( power->RetCapacity() > 1.0f )
- {
- m_displayText->DisplayError(ERR_RESEARCH_TYPE, m_object);
- return false;
- }
- if ( power->RetEnergy() < 1.0f )
- {
- m_displayText->DisplayError(ERR_RESEARCH_ENERGY, m_object);
- return false;
- }
-
- time = SEARCH_TIME;
- if ( event.event == EVENT_OBJECT_RTANK ) time *= 0.3f;
- if ( event.event == EVENT_OBJECT_RFLY ) time *= 0.3f;
- if ( event.event == EVENT_OBJECT_RATOMIC ) time *= 2.0f;
-
- SetBusy(true);
- InitProgressTotal(time);
- UpdateInterface();
-
- m_channelSound = m_sound->Play(SOUND_RESEARCH, m_object->RetPosition(0), 0.0f, 1.0f, true);
- m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, time-4.0f, SOPER_CONTINUE);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP);
-
- m_phase = ALP_SEARCH;
- m_progress = 0.0f;
- m_speed = 1.0f/time;
- return true;
- }
-
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
- }
- return true;
- }
-
- UpdateInterface(event.rTime);
- EventProgress(event.rTime);
-
- angle = m_time*0.1f;
- m_object->SetAngleY(1, angle); // rotates the antenna
-
- angle = (30.0f+sinf(m_time*0.3f)*20.0f)*Math::PI/180.0f;
- m_object->SetAngleZ(2, angle); // directs the antenna
-
- if ( m_phase == ALP_WAIT )
- {
- FireStopUpdate(m_progress, false); // extinguished
- return true;
- }
-
- if ( m_phase == ALP_SEARCH )
- {
- FireStopUpdate(m_progress, true); // flashes
- if ( m_progress < 1.0f )
- {
- power = m_object->RetPower();
- if ( power == 0 ) // more battery?
- {
- SetBusy(false);
- UpdateInterface();
-
- m_phase = ALP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- return true;
- }
- power->SetEnergy(1.0f-m_progress);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*6.0f;
- pos.z += (Math::Rand()-0.5f)*6.0f;
- pos.y += 11.0f;
- speed.x = (Math::Rand()-0.5f)*2.0f;
- speed.z = (Math::Rand()-0.5f)*2.0f;
- speed.y = Math::Rand()*20.0f;
- dim.x = Math::Rand()*1.0f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR);
- }
- }
- else
- {
- SetResearch(m_research); // research done
- m_displayText->DisplayError(INFO_RESEARCH, m_object);
-
- message = ERR_OK;
- if ( m_research == EVENT_OBJECT_RTANK ) message = INFO_RESEARCHTANK;
- if ( m_research == EVENT_OBJECT_RFLY ) message = INFO_RESEARCHFLY;
- if ( m_research == EVENT_OBJECT_RTHUMP ) message = INFO_RESEARCHTHUMP;
- if ( m_research == EVENT_OBJECT_RCANON ) message = INFO_RESEARCHCANON;
- if ( m_research == EVENT_OBJECT_RTOWER ) message = INFO_RESEARCHTOWER;
- if ( m_research == EVENT_OBJECT_RPHAZER ) message = INFO_RESEARCHPHAZER;
- if ( m_research == EVENT_OBJECT_RSHIELD ) message = INFO_RESEARCHSHIELD;
- if ( m_research == EVENT_OBJECT_RATOMIC ) message = INFO_RESEARCHATOMIC;
- if ( message != ERR_OK )
- {
- m_displayText->DisplayError(message, m_object);
- }
-
- SetBusy(false);
- UpdateInterface();
-
- m_phase = ALP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoResearch::RetError()
-{
- CObject* power;
-
- if ( m_phase == ALP_SEARCH )
- {
- return ERR_OK;
- }
-
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- power = m_object->RetPower();
- if ( power == 0 )
- {
- return ERR_RESEARCH_POWER;
- }
- if ( power != 0 && power->RetCapacity() > 1.0f )
- {
- return ERR_RESEARCH_TYPE;
- }
- if ( power != 0 && power->RetEnergy() < 1.0f )
- {
- return ERR_RESEARCH_ENERGY;
- }
-
- return ERR_OK;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoResearch::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, dim, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- dim.x = 33.0f/640.0f;
- dim.y = 33.0f/480.0f;
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*7.0f;
- pos.y = oy+sy*1.0f;
- pw->CreateButton(pos, dim, 64+0, EVENT_OBJECT_RTANK);
-
- pos.x = ox+sx*8.0f;
- pos.y = oy+sy*1.0f;
- pw->CreateButton(pos, dim, 64+1, EVENT_OBJECT_RFLY);
-
- pos.x = ox+sx*9.0f;
- pos.y = oy+sy*1.0f;
- pw->CreateButton(pos, dim, 64+3, EVENT_OBJECT_RCANON);
-
- pos.x = ox+sx*10.0f;
- pos.y = oy+sy*1.0f;
- pw->CreateButton(pos, dim, 64+4, EVENT_OBJECT_RTOWER);
-
- pos.x = ox+sx*7.0f;
- pos.y = oy+sy*0.0f;
- pw->CreateButton(pos, dim, 64+7, EVENT_OBJECT_RATOMIC);
-
- pos.x = ox+sx*8.0f;
- pos.y = oy+sy*0.0f;
- pw->CreateButton(pos, dim, 64+2, EVENT_OBJECT_RTHUMP);
-
- pos.x = ox+sx*9.0f;
- pos.y = oy+sy*0.0f;
- pw->CreateButton(pos, dim, 64+6, EVENT_OBJECT_RSHIELD);
-
- pos.x = ox+sx*10.0f;
- pos.y = oy+sy*0.0f;
- pw->CreateButton(pos, dim, 64+5, EVENT_OBJECT_RPHAZER);
-
- pos.x = ox+sx*14.5f;
- pos.y = oy+sy*0;
- ddim.x = 14.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 102, EVENT_OBJECT_TYPE);
-
- UpdateInterface();
-
- return true;
-}
-
-// Updates the status of all interface buttons.
-
-void CAutoResearch::UpdateInterface()
-{
- CWindow* pw;
-
- if ( !m_object->RetSelect() ) return;
-
- CAuto::UpdateInterface();
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- DeadInterface(pw, EVENT_OBJECT_RTANK, g_researchEnable&RESEARCH_TANK);
- DeadInterface(pw, EVENT_OBJECT_RFLY, g_researchEnable&RESEARCH_FLY);
- DeadInterface(pw, EVENT_OBJECT_RTHUMP, g_researchEnable&RESEARCH_THUMP);
- DeadInterface(pw, EVENT_OBJECT_RCANON, g_researchEnable&RESEARCH_CANON);
- DeadInterface(pw, EVENT_OBJECT_RTOWER, g_researchEnable&RESEARCH_TOWER);
- DeadInterface(pw, EVENT_OBJECT_RPHAZER, g_researchEnable&RESEARCH_PHAZER);
- DeadInterface(pw, EVENT_OBJECT_RSHIELD, g_researchEnable&RESEARCH_SHIELD);
- DeadInterface(pw, EVENT_OBJECT_RATOMIC, g_researchEnable&RESEARCH_ATOMIC);
-
- OkayButton(pw, EVENT_OBJECT_RTANK);
- OkayButton(pw, EVENT_OBJECT_RFLY);
- OkayButton(pw, EVENT_OBJECT_RTHUMP);
- OkayButton(pw, EVENT_OBJECT_RCANON);
- OkayButton(pw, EVENT_OBJECT_RTOWER);
- OkayButton(pw, EVENT_OBJECT_RPHAZER);
- OkayButton(pw, EVENT_OBJECT_RSHIELD);
- OkayButton(pw, EVENT_OBJECT_RATOMIC);
-
- VisibleInterface(pw, EVENT_OBJECT_RTANK, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RFLY, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RTHUMP, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RCANON, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RTOWER, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RPHAZER, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RSHIELD, !m_bBusy);
- VisibleInterface(pw, EVENT_OBJECT_RATOMIC, !m_bBusy);
-}
-
-// Updates the state of all buttons on the interface,
-// following the time that elapses ...
-
-void CAutoResearch::UpdateInterface(float rTime)
-{
- CWindow* pw;
- CGauge* pg;
- CObject* power;
- float energy;
-
- CAuto::UpdateInterface(rTime);
-
- if ( m_time < m_lastUpdateTime+0.1f ) return;
- m_lastUpdateTime = m_time;
-
- if ( !m_object->RetSelect() ) return;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY);
- if ( pg != 0 )
- {
- energy = 0.0f;
- power = m_object->RetPower();
- if ( power != 0 )
- {
- energy = power->RetEnergy();
- }
- pg->SetLevel(energy);
- }
-}
-
-// Research shows already performed button.
-
-void CAutoResearch::OkayButton(CWindow *pw, EventMsg event)
-{
- CControl* control;
-
- control = pw->SearchControl(event);
- if ( control == 0 ) return;
-
- control->SetState(STATE_OKAY, TestResearch(event));
-}
-
-
-// Test whether a search has already been done.
-
-bool CAutoResearch::TestResearch(EventMsg event)
-{
- if ( event == EVENT_OBJECT_RTANK ) return (g_researchDone & RESEARCH_TANK );
- if ( event == EVENT_OBJECT_RFLY ) return (g_researchDone & RESEARCH_FLY );
- if ( event == EVENT_OBJECT_RTHUMP ) return (g_researchDone & RESEARCH_THUMP );
- if ( event == EVENT_OBJECT_RCANON ) return (g_researchDone & RESEARCH_CANON );
- if ( event == EVENT_OBJECT_RTOWER ) return (g_researchDone & RESEARCH_TOWER );
- if ( event == EVENT_OBJECT_RPHAZER ) return (g_researchDone & RESEARCH_PHAZER );
- if ( event == EVENT_OBJECT_RSHIELD ) return (g_researchDone & RESEARCH_SHIELD);
- if ( event == EVENT_OBJECT_RATOMIC ) return (g_researchDone & RESEARCH_ATOMIC);
-
- return false;
-}
-
-// Indicates a search as made.
-
-void CAutoResearch::SetResearch(EventMsg event)
-{
- Event newEvent;
-
- if ( event == EVENT_OBJECT_RTANK ) g_researchDone |= RESEARCH_TANK;
- if ( event == EVENT_OBJECT_RFLY ) g_researchDone |= RESEARCH_FLY;
- if ( event == EVENT_OBJECT_RTHUMP ) g_researchDone |= RESEARCH_THUMP;
- if ( event == EVENT_OBJECT_RCANON ) g_researchDone |= RESEARCH_CANON;
- if ( event == EVENT_OBJECT_RTOWER ) g_researchDone |= RESEARCH_TOWER;
- if ( event == EVENT_OBJECT_RPHAZER ) g_researchDone |= RESEARCH_PHAZER;
- if ( event == EVENT_OBJECT_RSHIELD ) g_researchDone |= RESEARCH_SHIELD;
- if ( event == EVENT_OBJECT_RATOMIC ) g_researchDone |= RESEARCH_ATOMIC;
-
- m_main->WriteFreeParam();
-
- m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE);
- m_event->AddEvent(newEvent);
- UpdateInterface();
-}
-
-
-// Updates the stop lights.
-
-void CAutoResearch::FireStopUpdate(float progress, bool bLightOn)
-{
- Math::Matrix* mat;
- Math::Vector pos, speed;
- Math::Point dim;
- int i;
-
- static float listpos[12] =
- {
- 9.5f, 0.0f,
- 4.7f, 8.2f,
- -4.7f, 8.2f,
- -9.5f, 0.0f,
- -4.7f, -8.2f,
- 4.7f, -8.2f,
- };
-
- if ( !bLightOn ) // �teint ?
- {
- for ( i=0 ; i<6 ; i++ )
- {
- if ( m_partiStop[i] != -1 )
- {
- m_particule->DeleteParticule(m_partiStop[i]);
- m_partiStop[i] = -1;
- }
- }
- return;
- }
-
- mat = m_object->RetWorldMatrix(0);
-
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 2.0f;
- dim.y = dim.x;
-
- for ( i=0 ; i<6 ; i++ )
- {
- if ( Math::Mod(progress, 0.025f) < 0.005f )
- {
- if ( m_partiStop[i] != -1 )
- {
- m_particule->DeleteParticule(m_partiStop[i]);
- m_partiStop[i] = -1;
- }
- }
- else
- {
- if ( m_partiStop[i] == -1 )
- {
- pos.x = listpos[i*2+0];
- pos.y = 11.5f;
- pos.z = listpos[i*2+1];
- pos = Math::Transform(*mat, pos);
- m_partiStop[i] = m_particule->CreateParticule(pos, speed,
- dim, PARTISELY,
- 1.0f, 0.0f, 0.0f);
- }
- }
- }
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoResearch::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ALP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- sprintf(name, " aResearch=%d", m_research);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoResearch::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoResearchPhase)OpInt(line, "aPhase", ALP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
- m_research = (EventMsg)OpInt(line, "aResearch", 0);
-
- m_lastUpdateTime = 0.0f;
- m_lastParticule = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autoresearch.h" + +#include "common/global.h" +#include "math/geometry.h" +#include "object/robotmain.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/gauge.h" +#include "ui/window.h" +#include "ui/displaytext.h" + + + +const float SEARCH_TIME = 30.0f; // duration of a research + + + +// Object's constructor. + +CAutoResearch::CAutoResearch(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + for ( i=0 ; i<6 ; i++ ) + { + m_partiStop[i] = -1; + } + m_channelSound = -1; + + Init(); +} + +// Object's destructor. + +CAutoResearch::~CAutoResearch() +{ +} + + +// Destroys the object. + +void CAutoResearch::DeleteObject(bool bAll) +{ + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + FireStopUpdate(0.0f, false); + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoResearch::Init() +{ + m_phase = ALP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; +} + + +// Management of an event. + +bool CAutoResearch::EventProcess(const Event &event) +{ + CObject* power; + Math::Vector pos, speed; + Error message; + Math::Point dim; + float angle, time; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + + if ( event.event == EVENT_UPDINTERFACE ) + { + if ( m_object->RetSelect() ) CreateInterface(true); + } + + if ( m_object->RetSelect() && // center selected? + (event.event == EVENT_OBJECT_RTANK || + event.event == EVENT_OBJECT_RFLY || + event.event == EVENT_OBJECT_RTHUMP || + event.event == EVENT_OBJECT_RCANON || + event.event == EVENT_OBJECT_RTOWER || + event.event == EVENT_OBJECT_RPHAZER || + event.event == EVENT_OBJECT_RSHIELD || + event.event == EVENT_OBJECT_RATOMIC ) ) + { + if ( m_phase != ALP_WAIT ) + { + return false; + } + + m_research = event.event; + + if ( TestResearch(m_research) ) + { + m_displayText->DisplayError(ERR_RESEARCH_ALREADY, m_object); + return false; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + m_displayText->DisplayError(ERR_RESEARCH_POWER, m_object); + return false; + } + if ( power->RetCapacity() > 1.0f ) + { + m_displayText->DisplayError(ERR_RESEARCH_TYPE, m_object); + return false; + } + if ( power->RetEnergy() < 1.0f ) + { + m_displayText->DisplayError(ERR_RESEARCH_ENERGY, m_object); + return false; + } + + time = SEARCH_TIME; + if ( event.event == EVENT_OBJECT_RTANK ) time *= 0.3f; + if ( event.event == EVENT_OBJECT_RFLY ) time *= 0.3f; + if ( event.event == EVENT_OBJECT_RATOMIC ) time *= 2.0f; + + SetBusy(true); + InitProgressTotal(time); + UpdateInterface(); + + m_channelSound = m_sound->Play(SOUND_RESEARCH, m_object->RetPosition(0), 0.0f, 1.0f, true); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, time-4.0f, SOPER_CONTINUE); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); + + m_phase = ALP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/time; + return true; + } + + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + } + return true; + } + + UpdateInterface(event.rTime); + EventProgress(event.rTime); + + angle = m_time*0.1f; + m_object->SetAngleY(1, angle); // rotates the antenna + + angle = (30.0f+sinf(m_time*0.3f)*20.0f)*Math::PI/180.0f; + m_object->SetAngleZ(2, angle); // directs the antenna + + if ( m_phase == ALP_WAIT ) + { + FireStopUpdate(m_progress, false); // extinguished + return true; + } + + if ( m_phase == ALP_SEARCH ) + { + FireStopUpdate(m_progress, true); // flashes + if ( m_progress < 1.0f ) + { + power = m_object->RetPower(); + if ( power == 0 ) // more battery? + { + SetBusy(false); + UpdateInterface(); + + m_phase = ALP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + return true; + } + power->SetEnergy(1.0f-m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*6.0f; + pos.z += (Math::Rand()-0.5f)*6.0f; + pos.y += 11.0f; + speed.x = (Math::Rand()-0.5f)*2.0f; + speed.z = (Math::Rand()-0.5f)*2.0f; + speed.y = Math::Rand()*20.0f; + dim.x = Math::Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR); + } + } + else + { + SetResearch(m_research); // research done + m_displayText->DisplayError(INFO_RESEARCH, m_object); + + message = ERR_OK; + if ( m_research == EVENT_OBJECT_RTANK ) message = INFO_RESEARCHTANK; + if ( m_research == EVENT_OBJECT_RFLY ) message = INFO_RESEARCHFLY; + if ( m_research == EVENT_OBJECT_RTHUMP ) message = INFO_RESEARCHTHUMP; + if ( m_research == EVENT_OBJECT_RCANON ) message = INFO_RESEARCHCANON; + if ( m_research == EVENT_OBJECT_RTOWER ) message = INFO_RESEARCHTOWER; + if ( m_research == EVENT_OBJECT_RPHAZER ) message = INFO_RESEARCHPHAZER; + if ( m_research == EVENT_OBJECT_RSHIELD ) message = INFO_RESEARCHSHIELD; + if ( m_research == EVENT_OBJECT_RATOMIC ) message = INFO_RESEARCHATOMIC; + if ( message != ERR_OK ) + { + m_displayText->DisplayError(message, m_object); + } + + SetBusy(false); + UpdateInterface(); + + m_phase = ALP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoResearch::RetError() +{ + CObject* power; + + if ( m_phase == ALP_SEARCH ) + { + return ERR_OK; + } + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + return ERR_RESEARCH_POWER; + } + if ( power != 0 && power->RetCapacity() > 1.0f ) + { + return ERR_RESEARCH_TYPE; + } + if ( power != 0 && power->RetEnergy() < 1.0f ) + { + return ERR_RESEARCH_ENERGY; + } + + return ERR_OK; +} + + +// Creates all the interface when the object is selected. + +bool CAutoResearch::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, dim, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + dim.x = 33.0f/640.0f; + dim.y = 33.0f/480.0f; + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+0, EVENT_OBJECT_RTANK); + + pos.x = ox+sx*8.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+1, EVENT_OBJECT_RFLY); + + pos.x = ox+sx*9.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+3, EVENT_OBJECT_RCANON); + + pos.x = ox+sx*10.0f; + pos.y = oy+sy*1.0f; + pw->CreateButton(pos, dim, 64+4, EVENT_OBJECT_RTOWER); + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+7, EVENT_OBJECT_RATOMIC); + + pos.x = ox+sx*8.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+2, EVENT_OBJECT_RTHUMP); + + pos.x = ox+sx*9.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+6, EVENT_OBJECT_RSHIELD); + + pos.x = ox+sx*10.0f; + pos.y = oy+sy*0.0f; + pw->CreateButton(pos, dim, 64+5, EVENT_OBJECT_RPHAZER); + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 102, EVENT_OBJECT_TYPE); + + UpdateInterface(); + + return true; +} + +// Updates the status of all interface buttons. + +void CAutoResearch::UpdateInterface() +{ + CWindow* pw; + + if ( !m_object->RetSelect() ) return; + + CAuto::UpdateInterface(); + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + DeadInterface(pw, EVENT_OBJECT_RTANK, g_researchEnable&RESEARCH_TANK); + DeadInterface(pw, EVENT_OBJECT_RFLY, g_researchEnable&RESEARCH_FLY); + DeadInterface(pw, EVENT_OBJECT_RTHUMP, g_researchEnable&RESEARCH_THUMP); + DeadInterface(pw, EVENT_OBJECT_RCANON, g_researchEnable&RESEARCH_CANON); + DeadInterface(pw, EVENT_OBJECT_RTOWER, g_researchEnable&RESEARCH_TOWER); + DeadInterface(pw, EVENT_OBJECT_RPHAZER, g_researchEnable&RESEARCH_PHAZER); + DeadInterface(pw, EVENT_OBJECT_RSHIELD, g_researchEnable&RESEARCH_SHIELD); + DeadInterface(pw, EVENT_OBJECT_RATOMIC, g_researchEnable&RESEARCH_ATOMIC); + + OkayButton(pw, EVENT_OBJECT_RTANK); + OkayButton(pw, EVENT_OBJECT_RFLY); + OkayButton(pw, EVENT_OBJECT_RTHUMP); + OkayButton(pw, EVENT_OBJECT_RCANON); + OkayButton(pw, EVENT_OBJECT_RTOWER); + OkayButton(pw, EVENT_OBJECT_RPHAZER); + OkayButton(pw, EVENT_OBJECT_RSHIELD); + OkayButton(pw, EVENT_OBJECT_RATOMIC); + + VisibleInterface(pw, EVENT_OBJECT_RTANK, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RFLY, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RTHUMP, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RCANON, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RTOWER, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RPHAZER, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RSHIELD, !m_bBusy); + VisibleInterface(pw, EVENT_OBJECT_RATOMIC, !m_bBusy); +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoResearch::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + CObject* power; + float energy; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + pg->SetLevel(energy); + } +} + +// Research shows already performed button. + +void CAutoResearch::OkayButton(CWindow *pw, EventMsg event) +{ + CControl* control; + + control = pw->SearchControl(event); + if ( control == 0 ) return; + + control->SetState(STATE_OKAY, TestResearch(event)); +} + + +// Test whether a search has already been done. + +bool CAutoResearch::TestResearch(EventMsg event) +{ + if ( event == EVENT_OBJECT_RTANK ) return (g_researchDone & RESEARCH_TANK ); + if ( event == EVENT_OBJECT_RFLY ) return (g_researchDone & RESEARCH_FLY ); + if ( event == EVENT_OBJECT_RTHUMP ) return (g_researchDone & RESEARCH_THUMP ); + if ( event == EVENT_OBJECT_RCANON ) return (g_researchDone & RESEARCH_CANON ); + if ( event == EVENT_OBJECT_RTOWER ) return (g_researchDone & RESEARCH_TOWER ); + if ( event == EVENT_OBJECT_RPHAZER ) return (g_researchDone & RESEARCH_PHAZER ); + if ( event == EVENT_OBJECT_RSHIELD ) return (g_researchDone & RESEARCH_SHIELD); + if ( event == EVENT_OBJECT_RATOMIC ) return (g_researchDone & RESEARCH_ATOMIC); + + return false; +} + +// Indicates a search as made. + +void CAutoResearch::SetResearch(EventMsg event) +{ + Event newEvent; + + if ( event == EVENT_OBJECT_RTANK ) g_researchDone |= RESEARCH_TANK; + if ( event == EVENT_OBJECT_RFLY ) g_researchDone |= RESEARCH_FLY; + if ( event == EVENT_OBJECT_RTHUMP ) g_researchDone |= RESEARCH_THUMP; + if ( event == EVENT_OBJECT_RCANON ) g_researchDone |= RESEARCH_CANON; + if ( event == EVENT_OBJECT_RTOWER ) g_researchDone |= RESEARCH_TOWER; + if ( event == EVENT_OBJECT_RPHAZER ) g_researchDone |= RESEARCH_PHAZER; + if ( event == EVENT_OBJECT_RSHIELD ) g_researchDone |= RESEARCH_SHIELD; + if ( event == EVENT_OBJECT_RATOMIC ) g_researchDone |= RESEARCH_ATOMIC; + + m_main->WriteFreeParam(); + + m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + m_event->AddEvent(newEvent); + UpdateInterface(); +} + + +// Updates the stop lights. + +void CAutoResearch::FireStopUpdate(float progress, bool bLightOn) +{ + Math::Matrix* mat; + Math::Vector pos, speed; + Math::Point dim; + int i; + + static float listpos[12] = + { + 9.5f, 0.0f, + 4.7f, 8.2f, + -4.7f, 8.2f, + -9.5f, 0.0f, + -4.7f, -8.2f, + 4.7f, -8.2f, + }; + + if ( !bLightOn ) // �teint ? + { + for ( i=0 ; i<6 ; i++ ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + return; + } + + mat = m_object->RetWorldMatrix(0); + + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + + for ( i=0 ; i<6 ; i++ ) + { + if ( Math::Mod(progress, 0.025f) < 0.005f ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + else + { + if ( m_partiStop[i] == -1 ) + { + pos.x = listpos[i*2+0]; + pos.y = 11.5f; + pos.z = listpos[i*2+1]; + pos = Math::Transform(*mat, pos); + m_partiStop[i] = m_particule->CreateParticule(pos, speed, + dim, PARTISELY, + 1.0f, 0.0f, 0.0f); + } + } + } +} + + +// Saves all parameters of the controller. + +bool CAutoResearch::Write(char *line) +{ + char name[100]; + + if ( m_phase == ALP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + sprintf(name, " aResearch=%d", m_research); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoResearch::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoResearchPhase)OpInt(line, "aPhase", ALP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_research = (EventMsg)OpInt(line, "aResearch", 0); + + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autoresearch.h b/src/object/auto/autoresearch.h index c36edd6..b60f4bd 100644 --- a/src/object/auto/autoresearch.h +++ b/src/object/auto/autoresearch.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/.
-
-// autoresearch.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoResearchPhase
-{
- ALP_WAIT = 1,
- ALP_SEARCH = 2, // research in progress
-};
-
-
-
-class CAutoResearch : public CAuto
-{
-public:
- CAutoResearch(CInstanceManager* iMan, CObject* object);
- ~CAutoResearch();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- void UpdateInterface();
- void UpdateInterface(float rTime);
- void OkayButton(CWindow *pw, EventMsg event);
- bool TestResearch(EventMsg event);
- void SetResearch(EventMsg event);
- void FireStopUpdate(float progress, bool bLightOn);
-
-protected:
- AutoResearchPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastUpdateTime;
- float m_lastParticule;
- EventMsg m_research;
- int m_partiStop[6];
- int m_channelSound;
-};
-
+// * 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/. + +// autoresearch.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoResearchPhase +{ + ALP_WAIT = 1, + ALP_SEARCH = 2, // research in progress +}; + + + +class CAutoResearch : public CAuto +{ +public: + CAutoResearch(CInstanceManager* iMan, CObject* object); + ~CAutoResearch(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + void UpdateInterface(); + void UpdateInterface(float rTime); + void OkayButton(CWindow *pw, EventMsg event); + bool TestResearch(EventMsg event); + void SetResearch(EventMsg event); + void FireStopUpdate(float progress, bool bLightOn); + +protected: + AutoResearchPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + EventMsg m_research; + int m_partiStop[6]; + int m_channelSound; +}; + diff --git a/src/object/auto/autoroot.cpp b/src/object/auto/autoroot.cpp index cd3435e..9282a01 100644 --- a/src/object/auto/autoroot.cpp +++ b/src/object/auto/autoroot.cpp @@ -1,120 +1,120 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autoroot.h"
-
-#include "old/particule.h"
-#include "old/terrain.h"
-#include "math/geometry.h"
-
-
-
-
-// Object's constructor.
-
-CAutoRoot::CAutoRoot(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
-}
-
-// Object's destructor.
-
-CAutoRoot::~CAutoRoot()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoRoot::DeleteObject(bool bAll)
-{
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoRoot::Init()
-{
- Math::Matrix* mat;
- Math::Vector pos, speed;
- Math::Point dim;
-
- m_time = 0.0f;
- m_lastParticule = 0.0f;
-
- mat = m_object->RetWorldMatrix(0);
- pos = Math::Vector(-5.0f, 28.0f, -4.0f); // peak position
- pos = Math::Transform(*mat, pos);
- m_center = pos;
-
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 100.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(m_center, speed, dim, PARTISPHERE5, 0.5f, 0.0f, 0.0f);
-
- m_terrain->AddFlyingLimit(pos, 100.0f, 80.0f, pos.y-60.0f);
-}
-
-
-// Management of an event.
-
-bool CAutoRoot::EventProcess(const Event &event)
-{
- Math::Vector pos, speed;
- Math::Point dim;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_object->SetZoomX(1, 1.0f+sinf(m_time*2.0f)*0.2f);
- m_object->SetZoomY(1, 1.0f+sinf(m_time*2.3f)*0.2f);
- m_object->SetZoomZ(1, 1.0f+sinf(m_time*2.7f)*0.2f);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time )
- {
- m_lastParticule = m_time;
-
- pos = m_center;
- pos.x += (Math::Rand()-0.5f)*8.0f;
- pos.z += (Math::Rand()-0.5f)*8.0f;
- pos.y += 0.0f;
- speed.x = (Math::Rand()-0.5f)*12.0f;
- speed.z = (Math::Rand()-0.5f)*12.0f;
- speed.y = Math::Rand()*12.0f;
- dim.x = Math::Rand()*6.0f+4.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIROOT, 1.0f, 0.0f, 0.0f);
- }
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoRoot::RetError()
-{
- return ERR_OK;
-}
-
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autoroot.h" + +#include "old/particule.h" +#include "old/terrain.h" +#include "math/geometry.h" + + + + +// Object's constructor. + +CAutoRoot::CAutoRoot(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); +} + +// Object's destructor. + +CAutoRoot::~CAutoRoot() +{ +} + + +// Destroys the object. + +void CAutoRoot::DeleteObject(bool bAll) +{ + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoRoot::Init() +{ + Math::Matrix* mat; + Math::Vector pos, speed; + Math::Point dim; + + m_time = 0.0f; + m_lastParticule = 0.0f; + + mat = m_object->RetWorldMatrix(0); + pos = Math::Vector(-5.0f, 28.0f, -4.0f); // peak position + pos = Math::Transform(*mat, pos); + m_center = pos; + + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 100.0f; + dim.y = dim.x; + m_particule->CreateParticule(m_center, speed, dim, PARTISPHERE5, 0.5f, 0.0f, 0.0f); + + m_terrain->AddFlyingLimit(pos, 100.0f, 80.0f, pos.y-60.0f); +} + + +// Management of an event. + +bool CAutoRoot::EventProcess(const Event &event) +{ + Math::Vector pos, speed; + Math::Point dim; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_object->SetZoomX(1, 1.0f+sinf(m_time*2.0f)*0.2f); + m_object->SetZoomY(1, 1.0f+sinf(m_time*2.3f)*0.2f); + m_object->SetZoomZ(1, 1.0f+sinf(m_time*2.7f)*0.2f); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + { + m_lastParticule = m_time; + + pos = m_center; + pos.x += (Math::Rand()-0.5f)*8.0f; + pos.z += (Math::Rand()-0.5f)*8.0f; + pos.y += 0.0f; + speed.x = (Math::Rand()-0.5f)*12.0f; + speed.z = (Math::Rand()-0.5f)*12.0f; + speed.y = Math::Rand()*12.0f; + dim.x = Math::Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIROOT, 1.0f, 0.0f, 0.0f); + } + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoRoot::RetError() +{ + return ERR_OK; +} + + diff --git a/src/object/auto/autoroot.h b/src/object/auto/autoroot.h index 8bf397d..1ecd5ba 100644 --- a/src/object/auto/autoroot.h +++ b/src/object/auto/autoroot.h @@ -1,44 +1,44 @@ -// * 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/.
-
-// autoroot.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-class CAutoRoot : public CAuto
-{
-public:
- CAutoRoot(CInstanceManager* iMan, CObject* object);
- ~CAutoRoot();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
-protected:
-
-protected:
- float m_lastParticule;
- Math::Vector m_center;
-};
-
+// * 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/. + +// autoroot.h + +#pragma once + + +#include "object/auto/auto.h" + + + +class CAutoRoot : public CAuto +{ +public: + CAutoRoot(CInstanceManager* iMan, CObject* object); + ~CAutoRoot(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + +protected: + +protected: + float m_lastParticule; + Math::Vector m_center; +}; + diff --git a/src/object/auto/autosafe.cpp b/src/object/auto/autosafe.cpp index 6965851..11aac18 100644 --- a/src/object/auto/autosafe.cpp +++ b/src/object/auto/autosafe.cpp @@ -1,612 +1,612 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autosafe.h"
-
-#include "common/iman.h"
-#include "math/geometry.h"
-#include "object/robotmain.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/window.h"
-
-
-const float OPEN_DELAY = 8.0f; // duration of opening
-
-
-// Object's constructor.
-
-CAutoSafe::CAutoSafe(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- int i;
-
- for ( i=0 ; i<4 ; i++ )
- {
- m_bKey[i] = false;
- m_keyParti[i] = -1;
- }
-
- m_bLock = false;
- m_lastParticule = 0.0f;
- m_channelSound = -1;
- Init();
-}
-
-// Object's destructor.
-
-CAutoSafe::~CAutoSafe()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoSafe::DeleteObject(bool bAll)
-{
- CObject* pObj;
-
- pObj = SearchVehicle();
- if ( pObj != 0 )
- {
- pObj->DeleteObject();
- delete pObj;
- }
-
- if ( m_channelSound != -1 )
- {
- m_sound->FlushEnvelope(m_channelSound);
- m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
- m_channelSound = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoSafe::Init()
-{
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastParticule = 0.0f;
-
- m_countKeys = 0;
- m_actualAngle = 0.0f;
- m_finalAngle = 0.0f;
-
- m_phase = ASAP_WAIT; // waiting ...
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoSafe::EventProcess(const Event &event)
-{
- CObject* pObj;
- Math::Vector pos, speed;
- Math::Point dim;
- int i, count;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_speed;
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
- }
- return true;
- }
-
- EventProgress(event.rTime);
-
- if ( !m_bLock )
- {
- pObj = SearchVehicle();
- if ( pObj != 0 )
- {
- pObj->SetLock(true); // object not yet usable
- m_main->CreateShortcuts();
- m_bLock = true;
- }
- }
-
- if ( m_phase == ASAP_WAIT )
- {
- if ( m_progress >= 1.0f )
- {
- count = CountKeys(); // count these key
- if ( count != m_countKeys )
- {
- m_countKeys = count;
-
- if ( count == 0 ) m_finalAngle = 0.0f*Math::PI/180.0f;
- if ( count == 1 ) m_finalAngle = 5.0f*Math::PI/180.0f;
- if ( count == 2 ) m_finalAngle = 10.0f*Math::PI/180.0f;
- if ( count == 3 ) m_finalAngle = 15.0f*Math::PI/180.0f;
- if ( count == 4 ) m_finalAngle = 120.0f*Math::PI/180.0f;
-
- if ( count == 4 ) // all the keys?
- {
- LockKeys();
-
- m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, true);
- m_sound->AddEnvelope(m_channelSound, 1.0f, 2.00f, OPEN_DELAY, SOPER_STOP);
-
- m_phase = ASAP_OPEN;
- m_progress = 0.0f;
- m_speed = 1.0f/OPEN_DELAY;
- return true;
- }
- else
- {
- m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, true);
- m_sound->AddEnvelope(m_channelSound, 1.0f, 0.35f, 0.5f, SOPER_STOP);
- }
- }
-
- m_phase = ASAP_WAIT;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ASAP_OPEN )
- {
- if ( m_progress < 1.0f )
- {
- DownKeys(m_progress);
-
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- for ( i=0 ; i<10 ; i++ )
- {
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*10.0f;
- pos.z += (Math::Rand()-0.5f)*10.0f;
- speed.x = (Math::Rand()-0.5f)*4.0f;
- speed.z = (Math::Rand()-0.5f)*4.0f;
- speed.y = Math::Rand()*15.0f;
- dim.x = Math::Rand()*6.0f+4.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f);
- }
-
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*10.0f;
- pos.z += (Math::Rand()-0.5f)*10.0f;
- speed.x = (Math::Rand()-0.5f)*4.0f;
- speed.z = (Math::Rand()-0.5f)*4.0f;
- speed.y = Math::Rand()*10.0f;
- dim.x = Math::Rand()*3.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f);
-
- for ( i=0 ; i<4 ; i++ )
- {
- pos = m_keyPos[i];
- speed.x = (Math::Rand()-0.5f)*2.0f;
- speed.z = (Math::Rand()-0.5f)*2.0f;
- speed.y = 1.0f+Math::Rand()*1.0f;
- dim.x = Math::Rand()*1.5f+1.5f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f);
- }
- }
- }
- else
- {
- DeleteKeys();
-
- pObj = SearchVehicle();
- if ( pObj != 0 )
- {
- pObj->SetLock(false); // object usable
- m_main->CreateShortcuts();
- }
-
- m_object->FlushCrashShere();
- m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f);
-
- m_sound->Play(SOUND_FINDING, m_object->RetPosition(0));
-
- m_phase = ASAP_FINISH;
- m_progress = 0.0f;
- m_speed = 1.0f/100.0f;
- }
- }
-
- if ( m_phase == ASAP_FINISH )
- {
- if ( m_progress >= 1.0f )
- {
- m_phase = ASAP_FINISH;
- m_progress = 0.0f;
- m_speed = 1.0f/100.0f;
- }
- }
-
- // Opens or closes the doors.
- if ( m_actualAngle != m_finalAngle )
- {
- if ( m_actualAngle < m_finalAngle )
- {
- m_actualAngle += (105.0f*Math::PI/180.0f)*event.rTime/OPEN_DELAY;
- if ( m_actualAngle > m_finalAngle ) m_actualAngle = m_finalAngle;
- }
- else
- {
- m_actualAngle -= (105.0f*Math::PI/180.0f)*event.rTime/OPEN_DELAY;
- if ( m_actualAngle < m_finalAngle ) m_actualAngle = m_finalAngle;
- }
- m_object->SetAngleZ(1, m_actualAngle);
- m_object->SetAngleZ(2, -m_actualAngle);
- }
-
- // Blinks the keys.
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 2.0f;
- dim.y = dim.x;
- for ( i=0 ; i<4 ; i++ )
- {
- if ( m_phase != ASAP_WAIT || !m_bKey[i] || Math::Mod(m_time, 1.0f) < 0.4f )
- {
- if ( m_keyParti[i] != -1 )
- {
- m_particule->DeleteParticule(m_keyParti[i]);
- m_keyParti[i] = -1;
- }
- }
- else
- {
- if ( m_keyParti[i] == -1 )
- {
- pos = m_keyPos[i];
- pos.y += 2.2f;
- m_keyParti[i] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f);
- }
- }
- }
-
- return true;
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoSafe::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 114, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoSafe::RetError()
-{
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
- return ERR_OK;
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoSafe::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ASAP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoSafe::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoSafePhase)OpInt(line, "aPhase", ASAP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
-
- m_lastParticule = 0.0f;
-
- return true;
-}
-
-
-// Counts the number of keys
-
-int CAutoSafe::CountKeys()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- Math::Point rot;
- ObjectType oType;
- float dist, angle, limit, cAngle, oAngle;
- int i, index;
-
- cPos = m_object->RetPosition(0);
- cAngle = m_object->RetAngleY(0);
-
- for ( index=0 ; index<4 ; index++ )
- {
- m_bKey[index] = false;
- m_keyPos[index] = cPos;
- }
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( pObj->RetTruck() != 0 ) continue;
-
- if ( oType != OBJECT_KEYa &&
- oType != OBJECT_KEYb &&
- oType != OBJECT_KEYc &&
- oType != OBJECT_KEYd ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::DistanceProjected(oPos, cPos);
- if ( dist > 20.0f ) continue;
-
- if ( oType == OBJECT_KEYa )
- {
- limit = Math::PI*1.0f;
- oAngle = Math::PI*0.0f;
- index = 0;
- }
- if ( oType == OBJECT_KEYb )
- {
- limit = Math::PI*0.0f;
- oAngle = Math::PI*1.0f;
- index = 1;
- }
- if ( oType == OBJECT_KEYc )
- {
- limit = Math::PI*1.5f;
- oAngle = Math::PI*0.5f;
- index = 2;
- }
- if ( oType == OBJECT_KEYd )
- {
- limit = Math::PI*0.5f;
- oAngle = Math::PI*0.0f;
- index = 3;
- }
-
- angle = Math::RotateAngle(oPos.x-cPos.x, oPos.z-cPos.z)+cAngle;
- if ( !Math::TestAngle(angle, limit-8.0f*Math::PI/180.0f, limit+8.0f*Math::PI/180.0f) ) continue;
-
- // Key changes the shape of the base.
- rot = Math::RotatePoint(Math::Point(cPos.x, cPos.z), limit-cAngle, Math::Point(cPos.x+16.0f, cPos.z));
- oPos.x = rot.x;
- oPos.z = rot.y;
- oPos.y = cPos.y+1.0f;
- pObj->SetPosition(0, oPos);
- pObj->SetAngleY(0, oAngle+cAngle);
- m_keyPos[index] = oPos;
-
- m_bKey[index] = true;
- }
-
- i = 0;
- for ( index=0 ; index<4 ; index++ )
- {
- if ( m_bKey[index] ) i++;
- }
- return i;
-}
-
-// Blocks all keys.
-
-void CAutoSafe::LockKeys()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType oType;
- float dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( pObj->RetTruck() != 0 ) continue;
-
- if ( oType != OBJECT_KEYa &&
- oType != OBJECT_KEYb &&
- oType != OBJECT_KEYc &&
- oType != OBJECT_KEYd ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::DistanceProjected(oPos, cPos);
- if ( dist > 20.0f ) continue;
-
- pObj->SetLock(true);
- }
-}
-
-// Sent down all the keys.
-
-void CAutoSafe::DownKeys(float progress)
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType oType;
- float dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( pObj->RetTruck() != 0 ) continue;
-
- if ( oType != OBJECT_KEYa &&
- oType != OBJECT_KEYb &&
- oType != OBJECT_KEYc &&
- oType != OBJECT_KEYd ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::DistanceProjected(oPos, cPos);
- if ( dist > 20.0f ) continue;
-
- oPos.y = cPos.y+1.0f-progress*2.2f;
- pObj->SetPosition(0, oPos);
- }
-}
-
-// Delete all the keys.
-
-void CAutoSafe::DeleteKeys()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType oType;
- float dist;
- int i;
- bool bDelete;
-
- cPos = m_object->RetPosition(0);
-
- do
- {
- bDelete = false;
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( pObj->RetTruck() != 0 ) continue;
-
- if ( oType != OBJECT_KEYa &&
- oType != OBJECT_KEYb &&
- oType != OBJECT_KEYc &&
- oType != OBJECT_KEYd ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::DistanceProjected(oPos, cPos);
- if ( dist > 20.0f ) continue;
-
- pObj->DeleteObject();
- delete pObj;
- bDelete = true;
- }
- }
- while ( bDelete );
-}
-
-// Seeking a vehicle in the safe.
-
-CObject* CAutoSafe::SearchVehicle()
-{
- CObject* pObj;
- Math::Vector cPos, oPos;
- ObjectType oType;
- float dist;
- int i;
-
- cPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( pObj == m_object ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::DistanceProjected(oPos, cPos);
- if ( dist <= 4.0f ) return pObj;
- }
- return 0;
-}
-
-
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autosafe.h" + +#include "common/iman.h" +#include "math/geometry.h" +#include "object/robotmain.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/window.h" + + +const float OPEN_DELAY = 8.0f; // duration of opening + + +// Object's constructor. + +CAutoSafe::CAutoSafe(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + for ( i=0 ; i<4 ; i++ ) + { + m_bKey[i] = false; + m_keyParti[i] = -1; + } + + m_bLock = false; + m_lastParticule = 0.0f; + m_channelSound = -1; + Init(); +} + +// Object's destructor. + +CAutoSafe::~CAutoSafe() +{ +} + + +// Destroys the object. + +void CAutoSafe::DeleteObject(bool bAll) +{ + CObject* pObj; + + pObj = SearchVehicle(); + if ( pObj != 0 ) + { + pObj->DeleteObject(); + delete pObj; + } + + if ( m_channelSound != -1 ) + { + m_sound->FlushEnvelope(m_channelSound); + m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP); + m_channelSound = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoSafe::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastParticule = 0.0f; + + m_countKeys = 0; + m_actualAngle = 0.0f; + m_finalAngle = 0.0f; + + m_phase = ASAP_WAIT; // waiting ... + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoSafe::EventProcess(const Event &event) +{ + CObject* pObj; + Math::Vector pos, speed; + Math::Point dim; + int i, count; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_speed; + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + } + return true; + } + + EventProgress(event.rTime); + + if ( !m_bLock ) + { + pObj = SearchVehicle(); + if ( pObj != 0 ) + { + pObj->SetLock(true); // object not yet usable + m_main->CreateShortcuts(); + m_bLock = true; + } + } + + if ( m_phase == ASAP_WAIT ) + { + if ( m_progress >= 1.0f ) + { + count = CountKeys(); // count these key + if ( count != m_countKeys ) + { + m_countKeys = count; + + if ( count == 0 ) m_finalAngle = 0.0f*Math::PI/180.0f; + if ( count == 1 ) m_finalAngle = 5.0f*Math::PI/180.0f; + if ( count == 2 ) m_finalAngle = 10.0f*Math::PI/180.0f; + if ( count == 3 ) m_finalAngle = 15.0f*Math::PI/180.0f; + if ( count == 4 ) m_finalAngle = 120.0f*Math::PI/180.0f; + + if ( count == 4 ) // all the keys? + { + LockKeys(); + + m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, true); + m_sound->AddEnvelope(m_channelSound, 1.0f, 2.00f, OPEN_DELAY, SOPER_STOP); + + m_phase = ASAP_OPEN; + m_progress = 0.0f; + m_speed = 1.0f/OPEN_DELAY; + return true; + } + else + { + m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, true); + m_sound->AddEnvelope(m_channelSound, 1.0f, 0.35f, 0.5f, SOPER_STOP); + } + } + + m_phase = ASAP_WAIT; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ASAP_OPEN ) + { + if ( m_progress < 1.0f ) + { + DownKeys(m_progress); + + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*10.0f; + pos.z += (Math::Rand()-0.5f)*10.0f; + speed.x = (Math::Rand()-0.5f)*4.0f; + speed.z = (Math::Rand()-0.5f)*4.0f; + speed.y = Math::Rand()*15.0f; + dim.x = Math::Rand()*6.0f+4.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + } + + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*10.0f; + pos.z += (Math::Rand()-0.5f)*10.0f; + speed.x = (Math::Rand()-0.5f)*4.0f; + speed.z = (Math::Rand()-0.5f)*4.0f; + speed.y = Math::Rand()*10.0f; + dim.x = Math::Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); + + for ( i=0 ; i<4 ; i++ ) + { + pos = m_keyPos[i]; + speed.x = (Math::Rand()-0.5f)*2.0f; + speed.z = (Math::Rand()-0.5f)*2.0f; + speed.y = 1.0f+Math::Rand()*1.0f; + dim.x = Math::Rand()*1.5f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); + } + } + } + else + { + DeleteKeys(); + + pObj = SearchVehicle(); + if ( pObj != 0 ) + { + pObj->SetLock(false); // object usable + m_main->CreateShortcuts(); + } + + m_object->FlushCrashShere(); + m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f); + + m_sound->Play(SOUND_FINDING, m_object->RetPosition(0)); + + m_phase = ASAP_FINISH; + m_progress = 0.0f; + m_speed = 1.0f/100.0f; + } + } + + if ( m_phase == ASAP_FINISH ) + { + if ( m_progress >= 1.0f ) + { + m_phase = ASAP_FINISH; + m_progress = 0.0f; + m_speed = 1.0f/100.0f; + } + } + + // Opens or closes the doors. + if ( m_actualAngle != m_finalAngle ) + { + if ( m_actualAngle < m_finalAngle ) + { + m_actualAngle += (105.0f*Math::PI/180.0f)*event.rTime/OPEN_DELAY; + if ( m_actualAngle > m_finalAngle ) m_actualAngle = m_finalAngle; + } + else + { + m_actualAngle -= (105.0f*Math::PI/180.0f)*event.rTime/OPEN_DELAY; + if ( m_actualAngle < m_finalAngle ) m_actualAngle = m_finalAngle; + } + m_object->SetAngleZ(1, m_actualAngle); + m_object->SetAngleZ(2, -m_actualAngle); + } + + // Blinks the keys. + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + for ( i=0 ; i<4 ; i++ ) + { + if ( m_phase != ASAP_WAIT || !m_bKey[i] || Math::Mod(m_time, 1.0f) < 0.4f ) + { + if ( m_keyParti[i] != -1 ) + { + m_particule->DeleteParticule(m_keyParti[i]); + m_keyParti[i] = -1; + } + } + else + { + if ( m_keyParti[i] == -1 ) + { + pos = m_keyPos[i]; + pos.y += 2.2f; + m_keyParti[i] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); + } + } + } + + return true; +} + + +// Creates all the interface when the object is selected. + +bool CAutoSafe::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 114, EVENT_OBJECT_TYPE); + + return true; +} + + +// Returns an error due the state of the automation. + +Error CAutoSafe::RetError() +{ + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + return ERR_OK; +} + + +// Saves all parameters of the controller. + +bool CAutoSafe::Write(char *line) +{ + char name[100]; + + if ( m_phase == ASAP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoSafe::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoSafePhase)OpInt(line, "aPhase", ASAP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + + m_lastParticule = 0.0f; + + return true; +} + + +// Counts the number of keys + +int CAutoSafe::CountKeys() +{ + CObject* pObj; + Math::Vector cPos, oPos; + Math::Point rot; + ObjectType oType; + float dist, angle, limit, cAngle, oAngle; + int i, index; + + cPos = m_object->RetPosition(0); + cAngle = m_object->RetAngleY(0); + + for ( index=0 ; index<4 ; index++ ) + { + m_bKey[index] = false; + m_keyPos[index] = cPos; + } + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::DistanceProjected(oPos, cPos); + if ( dist > 20.0f ) continue; + + if ( oType == OBJECT_KEYa ) + { + limit = Math::PI*1.0f; + oAngle = Math::PI*0.0f; + index = 0; + } + if ( oType == OBJECT_KEYb ) + { + limit = Math::PI*0.0f; + oAngle = Math::PI*1.0f; + index = 1; + } + if ( oType == OBJECT_KEYc ) + { + limit = Math::PI*1.5f; + oAngle = Math::PI*0.5f; + index = 2; + } + if ( oType == OBJECT_KEYd ) + { + limit = Math::PI*0.5f; + oAngle = Math::PI*0.0f; + index = 3; + } + + angle = Math::RotateAngle(oPos.x-cPos.x, oPos.z-cPos.z)+cAngle; + if ( !Math::TestAngle(angle, limit-8.0f*Math::PI/180.0f, limit+8.0f*Math::PI/180.0f) ) continue; + + // Key changes the shape of the base. + rot = Math::RotatePoint(Math::Point(cPos.x, cPos.z), limit-cAngle, Math::Point(cPos.x+16.0f, cPos.z)); + oPos.x = rot.x; + oPos.z = rot.y; + oPos.y = cPos.y+1.0f; + pObj->SetPosition(0, oPos); + pObj->SetAngleY(0, oAngle+cAngle); + m_keyPos[index] = oPos; + + m_bKey[index] = true; + } + + i = 0; + for ( index=0 ; index<4 ; index++ ) + { + if ( m_bKey[index] ) i++; + } + return i; +} + +// Blocks all keys. + +void CAutoSafe::LockKeys() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::DistanceProjected(oPos, cPos); + if ( dist > 20.0f ) continue; + + pObj->SetLock(true); + } +} + +// Sent down all the keys. + +void CAutoSafe::DownKeys(float progress) +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::DistanceProjected(oPos, cPos); + if ( dist > 20.0f ) continue; + + oPos.y = cPos.y+1.0f-progress*2.2f; + pObj->SetPosition(0, oPos); + } +} + +// Delete all the keys. + +void CAutoSafe::DeleteKeys() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType oType; + float dist; + int i; + bool bDelete; + + cPos = m_object->RetPosition(0); + + do + { + bDelete = false; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj->RetTruck() != 0 ) continue; + + if ( oType != OBJECT_KEYa && + oType != OBJECT_KEYb && + oType != OBJECT_KEYc && + oType != OBJECT_KEYd ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::DistanceProjected(oPos, cPos); + if ( dist > 20.0f ) continue; + + pObj->DeleteObject(); + delete pObj; + bDelete = true; + } + } + while ( bDelete ); +} + +// Seeking a vehicle in the safe. + +CObject* CAutoSafe::SearchVehicle() +{ + CObject* pObj; + Math::Vector cPos, oPos; + ObjectType oType; + float dist; + int i; + + cPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( pObj == m_object ) continue; + if ( pObj->RetTruck() != 0 ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::DistanceProjected(oPos, cPos); + if ( dist <= 4.0f ) return pObj; + } + return 0; +} + + + diff --git a/src/object/auto/autosafe.h b/src/object/auto/autosafe.h index 4194349..d17435b 100644 --- a/src/object/auto/autosafe.h +++ b/src/object/auto/autosafe.h @@ -1,74 +1,74 @@ -// * 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/.
-
-// autosafe.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoSafePhase
-{
- ASAP_WAIT = 1,
- ASAP_OPEN = 2,
- ASAP_FINISH = 3,
-};
-
-
-
-class CAutoSafe : public CAuto
-{
-public:
- CAutoSafe(CInstanceManager* iMan, CObject* object);
- ~CAutoSafe();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- int CountKeys();
- void LockKeys();
- void DownKeys(float progress);
- void DeleteKeys();
- CObject* SearchVehicle();
-
-protected:
- AutoSafePhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastParticule;
- int m_channelSound;
- bool m_bLock;
- int m_countKeys;
- float m_actualAngle;
- float m_finalAngle;
- bool m_bKey[4];
- Math::Vector m_keyPos[4];
- int m_keyParti[4];
-};
-
+// * 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/. + +// autosafe.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoSafePhase +{ + ASAP_WAIT = 1, + ASAP_OPEN = 2, + ASAP_FINISH = 3, +}; + + + +class CAutoSafe : public CAuto +{ +public: + CAutoSafe(CInstanceManager* iMan, CObject* object); + ~CAutoSafe(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + int CountKeys(); + void LockKeys(); + void DownKeys(float progress); + void DeleteKeys(); + CObject* SearchVehicle(); + +protected: + AutoSafePhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticule; + int m_channelSound; + bool m_bLock; + int m_countKeys; + float m_actualAngle; + float m_finalAngle; + bool m_bKey[4]; + Math::Vector m_keyPos[4]; + int m_keyParti[4]; +}; + diff --git a/src/object/auto/autostation.cpp b/src/object/auto/autostation.cpp index ddd5888..dba4ed8 100644 --- a/src/object/auto/autostation.cpp +++ b/src/object/auto/autostation.cpp @@ -1,370 +1,370 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autostation.h"
-
-#include "common/iman.h"
-#include "old/particule.h"
-#include "old/terrain.h"
-#include "math/geometry.h"
-#include "ui/interface.h"
-#include "ui/gauge.h"
-#include "ui/window.h"
-
-
-
-
-// Object's constructor.
-
-CAutoStation::CAutoStation(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- Init();
-}
-
-// Object's destructor.
-
-CAutoStation::~CAutoStation()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoStation::DeleteObject(bool bAll)
-{
- if ( m_soundChannel != -1 )
- {
- m_sound->Stop(m_soundChannel);
- m_soundChannel = -1;
- }
-
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoStation::Init()
-{
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastUpdateTime = 0.0f;
- m_lastParticule = 0.0f;
- m_soundChannel = -1;
- m_bLastVirus = false;
-
- CAuto::Init();
-}
-
-
-// Management of an event.
-
-bool CAutoStation::EventProcess(const Event &event)
-{
- Math::Matrix* mat;
- Math::Vector pos, ppos, speed;
- Math::Point dim;
- CObject* vehicule;
- CObject* power;
- TerrainRes res;
- float big, energy, used, add, freq;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( !m_bLastVirus )
- {
- m_bLastVirus = true;
- m_energyVirus = m_object->RetEnergy();
- }
-
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
-
- m_object->SetEnergy(Math::Rand());
- }
- return true;
- }
- else
- {
- if ( m_bLastVirus )
- {
- m_bLastVirus = false;
- m_object->SetEnergy(m_energyVirus);
- }
- }
-
- UpdateInterface(event.rTime);
-
- big = m_object->RetEnergy();
-
- res = m_terrain->RetResource(m_object->RetPosition(0));
- if ( res == TR_POWER )
- {
- big += event.rTime*0.01f; // recharges the large battery
- }
-
- used = big;
- freq = 1.0f;
- if ( big > 0.0f )
- {
- vehicule = SearchVehicle();
- if ( vehicule != 0 )
- {
- power = vehicule->RetPower();
- if ( power != 0 && power->RetCapacity() == 1.0f )
- {
- energy = power->RetEnergy();
- add = event.rTime*0.2f;
- if ( add > big*4.0f ) add = big*4.0f;
- if ( add > 1.0f-energy ) add = 1.0f-energy;
- energy += add; // Charging the battery
- power->SetEnergy(energy);
- if ( energy < freq ) freq = energy;
- big -= add/4.0f; // discharge the large battery
- }
-
- power = vehicule->RetFret();
- if ( power != 0 && power->RetType() == OBJECT_POWER )
- {
- energy = power->RetEnergy();
- add = event.rTime*0.2f;
- if ( add > big*4.0f ) add = big*4.0f;
- if ( add > 1.0f-energy ) add = 1.0f-energy;
- energy += add; // Charging the battery
- power->SetEnergy(energy);
- if ( energy < freq ) freq = energy;
- big -= add/4.0f; // discharge the large battery
- }
- }
- }
- used -= big; // energy used
-
- if ( freq < 1.0f ) // charging in progress?
- {
- freq = 1.0f+3.0f*freq;
- if ( m_soundChannel == -1 )
- {
- m_soundChannel = m_sound->Play(SOUND_STATION, m_object->RetPosition(0),
- 0.3f, freq, true);
- }
- m_sound->Frequency(m_soundChannel, freq);
- }
- else
- {
- if ( m_soundChannel != -1 )
- {
- m_sound->Stop(m_soundChannel);
- m_soundChannel = -1;
- }
- }
-
- if ( used != 0.0f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time )
- {
- m_lastParticule = m_time;
-
- mat = m_object->RetWorldMatrix(0);
- pos = Math::Vector(-15.0f, 7.0f, 0.0f); // battery position
- pos = Math::Transform(*mat, pos);
- speed.x = (Math::Rand()-0.5f)*20.0f;
- speed.y = (Math::Rand()-0.5f)*20.0f;
- speed.z = (Math::Rand()-0.5f)*20.0f;
- ppos.x = pos.x;
- ppos.y = pos.y+(Math::Rand()-0.5f)*4.0f;
- ppos.z = pos.z;
- dim.x = 1.5f;
- dim.y = 1.5f;
- m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f);
-
-#if 0
- ppos = pos;
- ppos.y += 1.0f;
- ppos.x += (Math::Rand()-0.5f)*3.0f;
- ppos.z += (Math::Rand()-0.5f)*3.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- speed.y = 2.5f+Math::Rand()*6.0f;
- dim.x = Math::Rand()*1.5f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(ppos, speed, dim, PARTISMOKE3, 4.0f);
-#else
- ppos = pos;
- ppos.y += 1.0f;
- ppos.x += (Math::Rand()-0.5f)*3.0f;
- ppos.z += (Math::Rand()-0.5f)*3.0f;
- speed.x = 0.0f;
- speed.z = 0.0f;
- speed.y = 2.5f+Math::Rand()*5.0f;
- dim.x = Math::Rand()*1.0f+0.6f;
- dim.y = dim.x;
- m_particule->CreateParticule(ppos, speed, dim, PARTIVAPOR, 3.0f);
-#endif
- }
-
- if ( big < 0.0f ) big = 0.0f;
- if ( big > 1.0f ) big = 1.0f;
- m_object->SetEnergy(big); // Shift the large battery
-
- return true;
-}
-
-
-// Seeking the vehicle on the station.
-
-CObject* CAutoStation::SearchVehicle()
-{
- CObject* pObj;
- Math::Vector sPos, oPos;
- ObjectType type;
- float dist;
- int i;
-
- sPos = m_object->RetPosition(0);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- type = pObj->RetType();
- if ( type != OBJECT_HUMAN &&
- type != OBJECT_MOBILEfa &&
- type != OBJECT_MOBILEta &&
- type != OBJECT_MOBILEwa &&
- type != OBJECT_MOBILEia &&
- type != OBJECT_MOBILEfc &&
- type != OBJECT_MOBILEtc &&
- type != OBJECT_MOBILEwc &&
- type != OBJECT_MOBILEic &&
- type != OBJECT_MOBILEfi &&
- type != OBJECT_MOBILEti &&
- type != OBJECT_MOBILEwi &&
- type != OBJECT_MOBILEii &&
- type != OBJECT_MOBILEfs &&
- type != OBJECT_MOBILEts &&
- type != OBJECT_MOBILEws &&
- type != OBJECT_MOBILEis &&
- type != OBJECT_MOBILErt &&
- type != OBJECT_MOBILErc &&
- type != OBJECT_MOBILErr &&
- type != OBJECT_MOBILErs &&
- type != OBJECT_MOBILEsa &&
- type != OBJECT_MOBILEft &&
- type != OBJECT_MOBILEtt &&
- type != OBJECT_MOBILEwt &&
- type != OBJECT_MOBILEit &&
- type != OBJECT_MOBILEdr ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Math::Distance(oPos, sPos);
- if ( dist <= 5.0f ) return pObj;
- }
-
- return 0;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoStation::RetError()
-{
- TerrainRes res;
-
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- res = m_terrain->RetResource(m_object->RetPosition(0));
- if ( res != TR_POWER ) return ERR_STATION_NULL;
-
- return ERR_OK;
-}
-
-
-// Crée toute l'interface lorsque l'objet est sélectionné .
-
-bool CAutoStation::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*14.5f;
- pos.y = oy+sy*0;
- ddim.x = 14.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 104, EVENT_OBJECT_TYPE);
-
- return true;
-}
-
-// Updates the state of all buttons on the interface,
-// following the time that elapses ...
-
-void CAutoStation::UpdateInterface(float rTime)
-{
- CWindow* pw;
- CGauge* pg;
-
- CAuto::UpdateInterface(rTime);
-
- if ( m_time < m_lastUpdateTime+0.1f ) return;
- m_lastUpdateTime = m_time;
-
- if ( !m_object->RetSelect() ) return;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY);
- if ( pg != 0 )
- {
- pg->SetLevel(m_object->RetEnergy());
- }
-}
-
-
+// * 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/. + + +#include <stdio.h> + +#include "object/auto/autostation.h" + +#include "common/iman.h" +#include "old/particule.h" +#include "old/terrain.h" +#include "math/geometry.h" +#include "ui/interface.h" +#include "ui/gauge.h" +#include "ui/window.h" + + + + +// Object's constructor. + +CAutoStation::CAutoStation(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + Init(); +} + +// Object's destructor. + +CAutoStation::~CAutoStation() +{ +} + + +// Destroys the object. + +void CAutoStation::DeleteObject(bool bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->Stop(m_soundChannel); + m_soundChannel = -1; + } + + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoStation::Init() +{ + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; + m_soundChannel = -1; + m_bLastVirus = false; + + CAuto::Init(); +} + + +// Management of an event. + +bool CAutoStation::EventProcess(const Event &event) +{ + Math::Matrix* mat; + Math::Vector pos, ppos, speed; + Math::Point dim; + CObject* vehicule; + CObject* power; + TerrainRes res; + float big, energy, used, add, freq; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( !m_bLastVirus ) + { + m_bLastVirus = true; + m_energyVirus = m_object->RetEnergy(); + } + + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + m_object->SetEnergy(Math::Rand()); + } + return true; + } + else + { + if ( m_bLastVirus ) + { + m_bLastVirus = false; + m_object->SetEnergy(m_energyVirus); + } + } + + UpdateInterface(event.rTime); + + big = m_object->RetEnergy(); + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res == TR_POWER ) + { + big += event.rTime*0.01f; // recharges the large battery + } + + used = big; + freq = 1.0f; + if ( big > 0.0f ) + { + vehicule = SearchVehicle(); + if ( vehicule != 0 ) + { + power = vehicule->RetPower(); + if ( power != 0 && power->RetCapacity() == 1.0f ) + { + energy = power->RetEnergy(); + add = event.rTime*0.2f; + if ( add > big*4.0f ) add = big*4.0f; + if ( add > 1.0f-energy ) add = 1.0f-energy; + energy += add; // Charging the battery + power->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } + + power = vehicule->RetFret(); + if ( power != 0 && power->RetType() == OBJECT_POWER ) + { + energy = power->RetEnergy(); + add = event.rTime*0.2f; + if ( add > big*4.0f ) add = big*4.0f; + if ( add > 1.0f-energy ) add = 1.0f-energy; + energy += add; // Charging the battery + power->SetEnergy(energy); + if ( energy < freq ) freq = energy; + big -= add/4.0f; // discharge the large battery + } + } + } + used -= big; // energy used + + if ( freq < 1.0f ) // charging in progress? + { + freq = 1.0f+3.0f*freq; + if ( m_soundChannel == -1 ) + { + m_soundChannel = m_sound->Play(SOUND_STATION, m_object->RetPosition(0), + 0.3f, freq, true); + } + m_sound->Frequency(m_soundChannel, freq); + } + else + { + if ( m_soundChannel != -1 ) + { + m_sound->Stop(m_soundChannel); + m_soundChannel = -1; + } + } + + if ( used != 0.0f && + m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + { + m_lastParticule = m_time; + + mat = m_object->RetWorldMatrix(0); + pos = Math::Vector(-15.0f, 7.0f, 0.0f); // battery position + pos = Math::Transform(*mat, pos); + speed.x = (Math::Rand()-0.5f)*20.0f; + speed.y = (Math::Rand()-0.5f)*20.0f; + speed.z = (Math::Rand()-0.5f)*20.0f; + ppos.x = pos.x; + ppos.y = pos.y+(Math::Rand()-0.5f)*4.0f; + ppos.z = pos.z; + dim.x = 1.5f; + dim.y = 1.5f; + m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + +#if 0 + ppos = pos; + ppos.y += 1.0f; + ppos.x += (Math::Rand()-0.5f)*3.0f; + ppos.z += (Math::Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 2.5f+Math::Rand()*6.0f; + dim.x = Math::Rand()*1.5f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(ppos, speed, dim, PARTISMOKE3, 4.0f); +#else + ppos = pos; + ppos.y += 1.0f; + ppos.x += (Math::Rand()-0.5f)*3.0f; + ppos.z += (Math::Rand()-0.5f)*3.0f; + speed.x = 0.0f; + speed.z = 0.0f; + speed.y = 2.5f+Math::Rand()*5.0f; + dim.x = Math::Rand()*1.0f+0.6f; + dim.y = dim.x; + m_particule->CreateParticule(ppos, speed, dim, PARTIVAPOR, 3.0f); +#endif + } + + if ( big < 0.0f ) big = 0.0f; + if ( big > 1.0f ) big = 1.0f; + m_object->SetEnergy(big); // Shift the large battery + + return true; +} + + +// Seeking the vehicle on the station. + +CObject* CAutoStation::SearchVehicle() +{ + CObject* pObj; + Math::Vector sPos, oPos; + ObjectType type; + float dist; + int i; + + sPos = m_object->RetPosition(0); + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + type = pObj->RetType(); + if ( type != OBJECT_HUMAN && + type != OBJECT_MOBILEfa && + type != OBJECT_MOBILEta && + type != OBJECT_MOBILEwa && + type != OBJECT_MOBILEia && + type != OBJECT_MOBILEfc && + type != OBJECT_MOBILEtc && + type != OBJECT_MOBILEwc && + type != OBJECT_MOBILEic && + type != OBJECT_MOBILEfi && + type != OBJECT_MOBILEti && + type != OBJECT_MOBILEwi && + type != OBJECT_MOBILEii && + type != OBJECT_MOBILEfs && + type != OBJECT_MOBILEts && + type != OBJECT_MOBILEws && + type != OBJECT_MOBILEis && + type != OBJECT_MOBILErt && + type != OBJECT_MOBILErc && + type != OBJECT_MOBILErr && + type != OBJECT_MOBILErs && + type != OBJECT_MOBILEsa && + type != OBJECT_MOBILEft && + type != OBJECT_MOBILEtt && + type != OBJECT_MOBILEwt && + type != OBJECT_MOBILEit && + type != OBJECT_MOBILEdr ) continue; + + oPos = pObj->RetPosition(0); + dist = Math::Distance(oPos, sPos); + if ( dist <= 5.0f ) return pObj; + } + + return 0; +} + + +// Returns an error due the state of the automation. + +Error CAutoStation::RetError() +{ + TerrainRes res; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + res = m_terrain->RetResource(m_object->RetPosition(0)); + if ( res != TR_POWER ) return ERR_STATION_NULL; + + return ERR_OK; +} + + +// Crée toute l'interface lorsque l'objet est sélectionné . + +bool CAutoStation::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 104, EVENT_OBJECT_TYPE); + + return true; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoStation::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + pg->SetLevel(m_object->RetEnergy()); + } +} + + diff --git a/src/object/auto/autostation.h b/src/object/auto/autostation.h index b4584f2..5bf2b72 100644 --- a/src/object/auto/autostation.h +++ b/src/object/auto/autostation.h @@ -1,56 +1,56 @@ -// * 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/.
-
-// autostation.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-class CAutoStation : public CAuto
-{
-public:
- CAutoStation(CInstanceManager* iMan, CObject* object);
- ~CAutoStation();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
-protected:
- void UpdateInterface(float rTime);
-
- CObject* SearchVehicle();
-
-protected:
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastUpdateTime;
- float m_lastParticule;
- int m_soundChannel;
- Math::Vector m_fretPos;
- bool m_bLastVirus;
- float m_energyVirus;
-};
-
+// * 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/. + +// autostation.h + +#pragma once + + +#include "object/auto/auto.h" + + + +class CAutoStation : public CAuto +{ +public: + CAutoStation(CInstanceManager* iMan, CObject* object); + ~CAutoStation(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + +protected: + void UpdateInterface(float rTime); + + CObject* SearchVehicle(); + +protected: + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + int m_soundChannel; + Math::Vector m_fretPos; + bool m_bLastVirus; + float m_energyVirus; +}; + diff --git a/src/object/auto/autotower.cpp b/src/object/auto/autotower.cpp index ec92341..5f185fe 100644 --- a/src/object/auto/autotower.cpp +++ b/src/object/auto/autotower.cpp @@ -1,541 +1,541 @@ -// * 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/.
-
-
-#include <stdio.h>
-
-#include "object/auto/autotower.h"
-
-#include "common/iman.h"
-#include "math/geometry.h"
-#include "physics/physics.h"
-#include "script/cmdtoken.h"
-#include "ui/interface.h"
-#include "ui/displaytext.h"
-#include "ui/window.h"
-#include "ui/gauge.h"
-
-
-const float TOWER_SCOPE = 200.0f; // range of beam
-const float ENERGY_FIRE = 0.125f; // energy consumed by fire
-
-
-// Object's constructor.
-
-CAutoTower::CAutoTower(CInstanceManager* iMan, CObject* object)
- : CAuto(iMan, object)
-{
- int i;
-
- for ( i=0 ; i<4 ; i++ )
- {
- m_partiStop[i] = -1;
- }
-
- Init();
- m_phase = ATP_WAIT; // paused until the first Init ()
- m_time = 0.0f;
- m_lastUpdateTime = 0.0f;
-}
-
-// Object's destructor.
-
-CAutoTower::~CAutoTower()
-{
-}
-
-
-// Destroys the object.
-
-void CAutoTower::DeleteObject(bool bAll)
-{
- FireStopUpdate(0.0f, false);
- CAuto::DeleteObject(bAll);
-}
-
-
-// Initialize the object.
-
-void CAutoTower::Init()
-{
- m_phase = ATP_ZERO;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-
- m_time = 0.0f;
- m_timeVirus = 0.0f;
- m_lastUpdateTime = 0.0f;
- m_lastParticule = 0.0f;
-}
-
-
-// Management of an event.
-
-bool CAutoTower::EventProcess(const Event &event)
-{
- CObject* power;
- CObject* target;
- Math::Vector pos;
- float angle, energy, quick;
-
- CAuto::EventProcess(event);
-
- if ( m_engine->RetPause() ) return true;
- if ( event.event != EVENT_FRAME ) return true;
-
- m_timeVirus -= event.rTime;
-
- if ( m_object->RetVirusMode() ) // contaminated by a virus?
- {
- if ( m_timeVirus <= 0.0f )
- {
- m_timeVirus = 0.1f+Math::Rand()*0.3f;
-
- angle = m_object->RetAngleY(1);
- angle += Math::Rand()*0.5f;
- m_object->SetAngleY(1, angle);
-
- m_object->SetAngleZ(2, Math::Rand()*0.5f);
- }
- return true;
- }
-
- UpdateInterface(event.rTime);
-
- if ( m_phase == ATP_WAIT ) return true;
-
- m_progress += event.rTime*m_speed;
-
- if ( m_phase == ATP_ZERO )
- {
- FireStopUpdate(m_progress, true); // blinks
- if ( m_progress < 1.0f )
- {
- energy = 0.0f;
- power = m_object->RetPower();
- if ( power != 0 )
- {
- energy = power->RetEnergy();
- }
- if ( energy >= ENERGY_FIRE )
- {
- m_phase = ATP_SEARCH;
- m_progress = 0.0f;
- m_speed = 1.0f/3.0f;
- }
- }
- else
- {
- m_phase = ATP_ZERO;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- if ( m_phase == ATP_SEARCH )
- {
- FireStopUpdate(m_progress, false); // extinguished
- if ( m_progress < 1.0f )
- {
- quick = 1.0f;
-//? if ( g_researchDone & RESEARCH_QUICK ) quick = 3.0f;
-
- angle = m_object->RetAngleY(1);
- angle -= event.rTime*quick*2.0f;
- m_object->SetAngleY(1, angle);
-
- angle = m_object->RetAngleZ(2);
- angle += event.rTime*quick*0.5f;
- if ( angle > 0.0f ) angle = 0.0f;
- m_object->SetAngleZ(2, angle);
- }
- else
- {
- energy = 0.0f;
- power = m_object->RetPower();
- if ( power != 0 )
- {
- energy = power->RetEnergy();
- }
-
- target = SearchTarget(m_targetPos);
- if ( energy < ENERGY_FIRE )
- {
- m_displayText->DisplayError(ERR_TOWER_ENERGY, m_object);
- }
- if ( target == 0 || energy < ENERGY_FIRE )
- {
- m_phase = ATP_ZERO;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- else
- {
- pos = m_object->RetPosition(0);
- pos.y += 24.5f;
- m_angleYfinal = Math::RotateAngle(m_targetPos.x-pos.x, pos.z-m_targetPos.z); // CW !
- m_angleYfinal += Math::PI*2.0f;
- m_angleYfinal -= m_object->RetAngleY(0);
- m_angleYactual = Math::NormAngle(m_object->RetAngleY(1));
-
- m_angleZfinal = -Math::PI/2.0f;
- m_angleZfinal -= Math::RotateAngle(Math::DistanceProjected(m_targetPos, pos), pos.y-m_targetPos.y); // CW !
- m_angleZactual = m_object->RetAngleZ(2);
-
- m_phase = ATP_TURN;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
-//? if ( g_researchDone & RESEARCH_QUICK ) m_speed = 1.0f/0.2f;
- }
- }
- }
-
- if ( m_phase == ATP_TURN )
- {
- if ( m_progress < 1.0f )
- {
- angle = m_angleYactual+(m_angleYfinal-m_angleYactual)*m_progress;
- m_object->SetAngleY(1, angle);
-
- angle = m_angleZactual+(m_angleZfinal-m_angleZactual)*m_progress;
- m_object->SetAngleZ(2, angle);
- }
- else
- {
- m_object->SetAngleY(1, m_angleYfinal);
- m_object->SetAngleZ(2, m_angleZfinal);
-
- power = m_object->RetPower();
- if ( power != 0 )
- {
- energy = power->RetEnergy();
- energy -= ENERGY_FIRE/power->RetCapacity();
- power->SetEnergy(energy);
- }
-
- m_sound->Play(SOUND_GGG, m_object->RetPosition(0));
-
- m_phase = ATP_FIRE;
- m_progress = 0.0f;
- m_speed = 1.0f/1.5f;
- }
- }
-
- if ( m_phase == ATP_FIRE )
- {
- if ( m_progress == 0.0f )
- {
- pos = m_object->RetPosition(0);
- pos.y += 24.5f;
- m_particule->CreateRay(pos, m_targetPos, PARTIRAY1,
- Math::Point(5.0f, 5.0f), 1.5f);
- }
- if ( m_progress >= 1.0f )
- {
- m_phase = ATP_ZERO;
- m_progress = 0.0f;
- m_speed = 1.0f/1.0f;
- }
- }
-
- return true;
-}
-
-
-// Seeks the nearest target object.
-
-CObject* CAutoTower::SearchTarget(Math::Vector &impact)
-{
- CObject* pObj;
- CObject* pBest = 0;
- CPhysics* physics;
- Math::Vector iPos, oPos;
- ObjectType oType;
- float distance, min, radius, speed;
- int i;
-
- iPos = m_object->RetPosition(0);
- min = 1000000.0f;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( oType != OBJECT_MOTHER &&
- oType != OBJECT_ANT &&
- oType != OBJECT_SPIDER &&
- oType != OBJECT_BEE &&
- oType != OBJECT_WORM ) continue;
-
- if ( !pObj->RetActif() ) continue; // inactive?
-
-//? if ( g_researchDone & RESEARCH_QUICK )
- if ( false )
- {
- physics = pObj->RetPhysics();
- if ( physics != 0 )
- {
- speed = fabs(physics->RetLinMotionX(MO_REASPEED));
- if ( speed > 20.0f ) continue; // moving too fast?
- }
- }
-
- if ( !pObj->GetCrashSphere(0, oPos, radius) ) continue;
- distance = Math::Distance(oPos, iPos);
- if ( distance > TOWER_SCOPE ) continue; // too far
- if ( distance < min )
- {
- min = distance;
- pBest = pObj;
- }
- }
- if ( pBest == 0 ) return 0;
-
- impact = pBest->RetPosition(0);
- return pBest;
-}
-
-
-// Returns an error due the state of the automation.
-
-Error CAutoTower::RetError()
-{
- CObject* power;
-
- if ( m_object->RetVirusMode() )
- {
- return ERR_BAT_VIRUS;
- }
-
- power = m_object->RetPower();
- if ( power == 0 )
- {
- return ERR_TOWER_POWER; // no battery
- }
- else
- {
- if ( power->RetEnergy() < ENERGY_FIRE )
- {
- return ERR_TOWER_ENERGY; // not enough energy
- }
- }
- return ERR_OK;
-}
-
-
-// Updates the stop lights.
-
-void CAutoTower::FireStopUpdate(float progress, bool bLightOn)
-{
- Math::Matrix* mat;
- Math::Vector pos, speed;
- Math::Point dim;
- int i;
-
- static float listpos[8] =
- {
- 4.5f, 0.0f,
- 0.0f, 4.5f,
- -4.5f, 0.0f,
- 0.0f, -4.5f,
- };
-
- if ( !bLightOn ) // extinguished?
- {
- for ( i=0 ; i<4 ; i++ )
- {
- if ( m_partiStop[i] != -1 )
- {
- m_particule->DeleteParticule(m_partiStop[i]);
- m_partiStop[i] = -1;
- }
- }
- return;
- }
-
- mat = m_object->RetWorldMatrix(0);
-
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 2.0f;
- dim.y = dim.x;
-
- for ( i=0 ; i<4 ; i++ )
- {
- if ( Math::Mod(progress+i*0.125f, 0.5f) < 0.2f )
- {
- if ( m_partiStop[i] != -1 )
- {
- m_particule->DeleteParticule(m_partiStop[i]);
- m_partiStop[i] = -1;
- }
- }
- else
- {
- if ( m_partiStop[i] == -1 )
- {
- pos.x = listpos[i*2+0];
- pos.y = 18.0f;
- pos.z = listpos[i*2+1];
- pos = Transform(*mat, pos);
- m_partiStop[i] = m_particule->CreateParticule(pos, speed,
- dim, PARTISELR,
- 1.0f, 0.0f, 0.0f);
- }
- }
- }
-}
-
-
-// Creates all the interface when the object is selected.
-
-bool CAutoTower::CreateInterface(bool bSelect)
-{
- CWindow* pw;
- Math::Point pos, ddim;
- float ox, oy, sx, sy;
-
- CAuto::CreateInterface(bSelect);
-
- if ( !bSelect ) return true;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return false;
-
- ox = 3.0f/640.0f;
- oy = 3.0f/480.0f;
- sx = 33.0f/640.0f;
- sy = 33.0f/480.0f;
-
- pos.x = ox+sx*14.5f;
- pos.y = oy+sy*0;
- ddim.x = 14.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY);
-
- pos.x = ox+sx*0.0f;
- pos.y = oy+sy*0;
- ddim.x = 66.0f/640.0f;
- ddim.y = 66.0f/480.0f;
- pw->CreateGroup(pos, ddim, 107, EVENT_OBJECT_TYPE);
-
- pos.x = ox+sx*10.2f;
- pos.y = oy+sy*0.5f;
- ddim.x = 33.0f/640.0f;
- ddim.y = 33.0f/480.0f;
- pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT);
-
- return true;
-}
-
-// Updates the state of all buttons on the interface,
-// following the time that elapses ...
-
-void CAutoTower::UpdateInterface(float rTime)
-{
- CWindow* pw;
- CGauge* pg;
- CObject* power;
- float energy;
-
- CAuto::UpdateInterface(rTime);
-
- if ( m_time < m_lastUpdateTime+0.1f ) return;
- m_lastUpdateTime = m_time;
-
- if ( !m_object->RetSelect() ) return;
-
- pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
- if ( pw == 0 ) return;
-
- pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY);
- if ( pg != 0 )
- {
- energy = 0.0f;
- power = m_object->RetPower();
- if ( power != 0 )
- {
- energy = power->RetEnergy();
- }
- pg->SetLevel(energy);
- }
-}
-
-
-// Saves all parameters of the controller.
-
-bool CAutoTower::Write(char *line)
-{
- char name[100];
-
- if ( m_phase == ATP_WAIT ) return false;
-
- sprintf(name, " aExist=%d", 1);
- strcat(line, name);
-
- CAuto::Write(line);
-
- sprintf(name, " aPhase=%d", m_phase);
- strcat(line, name);
-
- sprintf(name, " aProgress=%.2f", m_progress);
- strcat(line, name);
-
- sprintf(name, " aSpeed=%.2f", m_speed);
- strcat(line, name);
-
- sprintf(name, " aTargetPos=%.2f;%.2f;%.2f", m_targetPos.x, m_targetPos.y, m_targetPos.z);
- strcat(line, name);
-
- sprintf(name, " aAngleYactual=%.2f", m_angleYactual);
- strcat(line, name);
-
- sprintf(name, " aAngleZactual=%.2f", m_angleZactual);
- strcat(line, name);
-
- sprintf(name, " aAngleYfinal=%.2f", m_angleYfinal);
- strcat(line, name);
-
- sprintf(name, " aAngleZfinal=%.2f", m_angleZfinal);
- strcat(line, name);
-
- return true;
-}
-
-// Restores all parameters of the controller.
-
-bool CAutoTower::Read(char *line)
-{
- if ( OpInt(line, "aExist", 0) == 0 ) return false;
-
- CAuto::Read(line);
-
- m_phase = (AutoTowerPhase)OpInt(line, "aPhase", ATP_WAIT);
- m_progress = OpFloat(line, "aProgress", 0.0f);
- m_speed = OpFloat(line, "aSpeed", 1.0f);
- m_targetPos = OpDir(line, "aTargetPos");
- m_angleYactual = OpFloat(line, "aAngleYactual", 0.0f);
- m_angleZactual = OpFloat(line, "aAngleZactual", 0.0f);
- m_angleYfinal = OpFloat(line, "aAngleYfinal", 0.0f);
- m_angleZfinal = OpFloat(line, "aAngleZfinal", 0.0f);
-
- m_lastUpdateTime = 0.0f;
-
- 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/. + + +#include <stdio.h> + +#include "object/auto/autotower.h" + +#include "common/iman.h" +#include "math/geometry.h" +#include "physics/physics.h" +#include "script/cmdtoken.h" +#include "ui/interface.h" +#include "ui/displaytext.h" +#include "ui/window.h" +#include "ui/gauge.h" + + +const float TOWER_SCOPE = 200.0f; // range of beam +const float ENERGY_FIRE = 0.125f; // energy consumed by fire + + +// Object's constructor. + +CAutoTower::CAutoTower(CInstanceManager* iMan, CObject* object) + : CAuto(iMan, object) +{ + int i; + + for ( i=0 ; i<4 ; i++ ) + { + m_partiStop[i] = -1; + } + + Init(); + m_phase = ATP_WAIT; // paused until the first Init () + m_time = 0.0f; + m_lastUpdateTime = 0.0f; +} + +// Object's destructor. + +CAutoTower::~CAutoTower() +{ +} + + +// Destroys the object. + +void CAutoTower::DeleteObject(bool bAll) +{ + FireStopUpdate(0.0f, false); + CAuto::DeleteObject(bAll); +} + + +// Initialize the object. + +void CAutoTower::Init() +{ + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastUpdateTime = 0.0f; + m_lastParticule = 0.0f; +} + + +// Management of an event. + +bool CAutoTower::EventProcess(const Event &event) +{ + CObject* power; + CObject* target; + Math::Vector pos; + float angle, energy, quick; + + CAuto::EventProcess(event); + + if ( m_engine->RetPause() ) return true; + if ( event.event != EVENT_FRAME ) return true; + + m_timeVirus -= event.rTime; + + if ( m_object->RetVirusMode() ) // contaminated by a virus? + { + if ( m_timeVirus <= 0.0f ) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + angle = m_object->RetAngleY(1); + angle += Math::Rand()*0.5f; + m_object->SetAngleY(1, angle); + + m_object->SetAngleZ(2, Math::Rand()*0.5f); + } + return true; + } + + UpdateInterface(event.rTime); + + if ( m_phase == ATP_WAIT ) return true; + + m_progress += event.rTime*m_speed; + + if ( m_phase == ATP_ZERO ) + { + FireStopUpdate(m_progress, true); // blinks + if ( m_progress < 1.0f ) + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + if ( energy >= ENERGY_FIRE ) + { + m_phase = ATP_SEARCH; + m_progress = 0.0f; + m_speed = 1.0f/3.0f; + } + } + else + { + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + if ( m_phase == ATP_SEARCH ) + { + FireStopUpdate(m_progress, false); // extinguished + if ( m_progress < 1.0f ) + { + quick = 1.0f; +//? if ( g_researchDone & RESEARCH_QUICK ) quick = 3.0f; + + angle = m_object->RetAngleY(1); + angle -= event.rTime*quick*2.0f; + m_object->SetAngleY(1, angle); + + angle = m_object->RetAngleZ(2); + angle += event.rTime*quick*0.5f; + if ( angle > 0.0f ) angle = 0.0f; + m_object->SetAngleZ(2, angle); + } + else + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + + target = SearchTarget(m_targetPos); + if ( energy < ENERGY_FIRE ) + { + m_displayText->DisplayError(ERR_TOWER_ENERGY, m_object); + } + if ( target == 0 || energy < ENERGY_FIRE ) + { + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + else + { + pos = m_object->RetPosition(0); + pos.y += 24.5f; + m_angleYfinal = Math::RotateAngle(m_targetPos.x-pos.x, pos.z-m_targetPos.z); // CW ! + m_angleYfinal += Math::PI*2.0f; + m_angleYfinal -= m_object->RetAngleY(0); + m_angleYactual = Math::NormAngle(m_object->RetAngleY(1)); + + m_angleZfinal = -Math::PI/2.0f; + m_angleZfinal -= Math::RotateAngle(Math::DistanceProjected(m_targetPos, pos), pos.y-m_targetPos.y); // CW ! + m_angleZactual = m_object->RetAngleZ(2); + + m_phase = ATP_TURN; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; +//? if ( g_researchDone & RESEARCH_QUICK ) m_speed = 1.0f/0.2f; + } + } + } + + if ( m_phase == ATP_TURN ) + { + if ( m_progress < 1.0f ) + { + angle = m_angleYactual+(m_angleYfinal-m_angleYactual)*m_progress; + m_object->SetAngleY(1, angle); + + angle = m_angleZactual+(m_angleZfinal-m_angleZactual)*m_progress; + m_object->SetAngleZ(2, angle); + } + else + { + m_object->SetAngleY(1, m_angleYfinal); + m_object->SetAngleZ(2, m_angleZfinal); + + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + energy -= ENERGY_FIRE/power->RetCapacity(); + power->SetEnergy(energy); + } + + m_sound->Play(SOUND_GGG, m_object->RetPosition(0)); + + m_phase = ATP_FIRE; + m_progress = 0.0f; + m_speed = 1.0f/1.5f; + } + } + + if ( m_phase == ATP_FIRE ) + { + if ( m_progress == 0.0f ) + { + pos = m_object->RetPosition(0); + pos.y += 24.5f; + m_particule->CreateRay(pos, m_targetPos, PARTIRAY1, + Math::Point(5.0f, 5.0f), 1.5f); + } + if ( m_progress >= 1.0f ) + { + m_phase = ATP_ZERO; + m_progress = 0.0f; + m_speed = 1.0f/1.0f; + } + } + + return true; +} + + +// Seeks the nearest target object. + +CObject* CAutoTower::SearchTarget(Math::Vector &impact) +{ + CObject* pObj; + CObject* pBest = 0; + CPhysics* physics; + Math::Vector iPos, oPos; + ObjectType oType; + float distance, min, radius, speed; + int i; + + iPos = m_object->RetPosition(0); + min = 1000000.0f; + + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + oType = pObj->RetType(); + if ( oType != OBJECT_MOTHER && + oType != OBJECT_ANT && + oType != OBJECT_SPIDER && + oType != OBJECT_BEE && + oType != OBJECT_WORM ) continue; + + if ( !pObj->RetActif() ) continue; // inactive? + +//? if ( g_researchDone & RESEARCH_QUICK ) + if ( false ) + { + physics = pObj->RetPhysics(); + if ( physics != 0 ) + { + speed = fabs(physics->RetLinMotionX(MO_REASPEED)); + if ( speed > 20.0f ) continue; // moving too fast? + } + } + + if ( !pObj->GetCrashSphere(0, oPos, radius) ) continue; + distance = Math::Distance(oPos, iPos); + if ( distance > TOWER_SCOPE ) continue; // too far + if ( distance < min ) + { + min = distance; + pBest = pObj; + } + } + if ( pBest == 0 ) return 0; + + impact = pBest->RetPosition(0); + return pBest; +} + + +// Returns an error due the state of the automation. + +Error CAutoTower::RetError() +{ + CObject* power; + + if ( m_object->RetVirusMode() ) + { + return ERR_BAT_VIRUS; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + return ERR_TOWER_POWER; // no battery + } + else + { + if ( power->RetEnergy() < ENERGY_FIRE ) + { + return ERR_TOWER_ENERGY; // not enough energy + } + } + return ERR_OK; +} + + +// Updates the stop lights. + +void CAutoTower::FireStopUpdate(float progress, bool bLightOn) +{ + Math::Matrix* mat; + Math::Vector pos, speed; + Math::Point dim; + int i; + + static float listpos[8] = + { + 4.5f, 0.0f, + 0.0f, 4.5f, + -4.5f, 0.0f, + 0.0f, -4.5f, + }; + + if ( !bLightOn ) // extinguished? + { + for ( i=0 ; i<4 ; i++ ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + return; + } + + mat = m_object->RetWorldMatrix(0); + + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 2.0f; + dim.y = dim.x; + + for ( i=0 ; i<4 ; i++ ) + { + if ( Math::Mod(progress+i*0.125f, 0.5f) < 0.2f ) + { + if ( m_partiStop[i] != -1 ) + { + m_particule->DeleteParticule(m_partiStop[i]); + m_partiStop[i] = -1; + } + } + else + { + if ( m_partiStop[i] == -1 ) + { + pos.x = listpos[i*2+0]; + pos.y = 18.0f; + pos.z = listpos[i*2+1]; + pos = Transform(*mat, pos); + m_partiStop[i] = m_particule->CreateParticule(pos, speed, + dim, PARTISELR, + 1.0f, 0.0f, 0.0f); + } + } + } +} + + +// Creates all the interface when the object is selected. + +bool CAutoTower::CreateInterface(bool bSelect) +{ + CWindow* pw; + Math::Point pos, ddim; + float ox, oy, sx, sy; + + CAuto::CreateInterface(bSelect); + + if ( !bSelect ) return true; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return false; + + ox = 3.0f/640.0f; + oy = 3.0f/480.0f; + sx = 33.0f/640.0f; + sy = 33.0f/480.0f; + + pos.x = ox+sx*14.5f; + pos.y = oy+sy*0; + ddim.x = 14.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 107, EVENT_OBJECT_TYPE); + + pos.x = ox+sx*10.2f; + pos.y = oy+sy*0.5f; + ddim.x = 33.0f/640.0f; + ddim.y = 33.0f/480.0f; + pw->CreateButton(pos, ddim, 41, EVENT_OBJECT_LIMIT); + + return true; +} + +// Updates the state of all buttons on the interface, +// following the time that elapses ... + +void CAutoTower::UpdateInterface(float rTime) +{ + CWindow* pw; + CGauge* pg; + CObject* power; + float energy; + + CAuto::UpdateInterface(rTime); + + if ( m_time < m_lastUpdateTime+0.1f ) return; + m_lastUpdateTime = m_time; + + if ( !m_object->RetSelect() ) return; + + pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + if ( pw == 0 ) return; + + pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + if ( pg != 0 ) + { + energy = 0.0f; + power = m_object->RetPower(); + if ( power != 0 ) + { + energy = power->RetEnergy(); + } + pg->SetLevel(energy); + } +} + + +// Saves all parameters of the controller. + +bool CAutoTower::Write(char *line) +{ + char name[100]; + + if ( m_phase == ATP_WAIT ) return false; + + sprintf(name, " aExist=%d", 1); + strcat(line, name); + + CAuto::Write(line); + + sprintf(name, " aPhase=%d", m_phase); + strcat(line, name); + + sprintf(name, " aProgress=%.2f", m_progress); + strcat(line, name); + + sprintf(name, " aSpeed=%.2f", m_speed); + strcat(line, name); + + sprintf(name, " aTargetPos=%.2f;%.2f;%.2f", m_targetPos.x, m_targetPos.y, m_targetPos.z); + strcat(line, name); + + sprintf(name, " aAngleYactual=%.2f", m_angleYactual); + strcat(line, name); + + sprintf(name, " aAngleZactual=%.2f", m_angleZactual); + strcat(line, name); + + sprintf(name, " aAngleYfinal=%.2f", m_angleYfinal); + strcat(line, name); + + sprintf(name, " aAngleZfinal=%.2f", m_angleZfinal); + strcat(line, name); + + return true; +} + +// Restores all parameters of the controller. + +bool CAutoTower::Read(char *line) +{ + if ( OpInt(line, "aExist", 0) == 0 ) return false; + + CAuto::Read(line); + + m_phase = (AutoTowerPhase)OpInt(line, "aPhase", ATP_WAIT); + m_progress = OpFloat(line, "aProgress", 0.0f); + m_speed = OpFloat(line, "aSpeed", 1.0f); + m_targetPos = OpDir(line, "aTargetPos"); + m_angleYactual = OpFloat(line, "aAngleYactual", 0.0f); + m_angleZactual = OpFloat(line, "aAngleZactual", 0.0f); + m_angleYfinal = OpFloat(line, "aAngleYfinal", 0.0f); + m_angleZfinal = OpFloat(line, "aAngleZfinal", 0.0f); + + m_lastUpdateTime = 0.0f; + + return true; +} + + diff --git a/src/object/auto/autotower.h b/src/object/auto/autotower.h index b64ad3d..c9393ff 100644 --- a/src/object/auto/autotower.h +++ b/src/object/auto/autotower.h @@ -1,74 +1,74 @@ -// * 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/.
-
-// autotower.h
-
-#pragma once
-
-
-#include "object/auto/auto.h"
-
-
-
-enum AutoTowerPhase
-{
- ATP_WAIT = 1,
- ATP_ZERO = 2, // more energy
- ATP_SEARCH = 3, // search a target
- ATP_TURN = 4, // turns to the target
- ATP_FIRE = 5, // shoots on the target
-};
-
-
-
-class CAutoTower : public CAuto
-{
-public:
- CAutoTower(CInstanceManager* iMan, CObject* object);
- ~CAutoTower();
-
- void DeleteObject(bool bAll=false);
-
- void Init();
- bool EventProcess(const Event &event);
- Error RetError();
-
- bool CreateInterface(bool bSelect);
-
- bool Write(char *line);
- bool Read(char *line);
-
-protected:
- void UpdateInterface(float rTime);
-
- CObject* SearchTarget(Math::Vector &impact);
- void FireStopUpdate(float progress, bool bLightOn);
-
-protected:
- AutoTowerPhase m_phase;
- float m_progress;
- float m_speed;
- float m_timeVirus;
- float m_lastUpdateTime;
- float m_lastParticule;
- Math::Vector m_targetPos;
- float m_angleYactual;
- float m_angleZactual;
- float m_angleYfinal;
- float m_angleZfinal;
- int m_partiStop[4];
-};
-
+// * 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/. + +// autotower.h + +#pragma once + + +#include "object/auto/auto.h" + + + +enum AutoTowerPhase +{ + ATP_WAIT = 1, + ATP_ZERO = 2, // more energy + ATP_SEARCH = 3, // search a target + ATP_TURN = 4, // turns to the target + ATP_FIRE = 5, // shoots on the target +}; + + + +class CAutoTower : public CAuto +{ +public: + CAutoTower(CInstanceManager* iMan, CObject* object); + ~CAutoTower(); + + void DeleteObject(bool bAll=false); + + void Init(); + bool EventProcess(const Event &event); + Error RetError(); + + bool CreateInterface(bool bSelect); + + bool Write(char *line); + bool Read(char *line); + +protected: + void UpdateInterface(float rTime); + + CObject* SearchTarget(Math::Vector &impact); + void FireStopUpdate(float progress, bool bLightOn); + +protected: + AutoTowerPhase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastUpdateTime; + float m_lastParticule; + Math::Vector m_targetPos; + float m_angleYactual; + float m_angleZactual; + float m_angleYfinal; + float m_angleZfinal; + int m_partiStop[4]; +}; + |