Basic support for teams and code battle missions

master
krzys-h 2015-06-26 22:07:55 +02:00
parent 2a672482a5
commit 78e09c757d
13 changed files with 157 additions and 32 deletions

View File

@ -642,6 +642,7 @@ bool CAutoFactory::CreateVehicle()
vehicle->UpdateMapping();
vehicle->SetLock(true); // not usable
vehicle->SetRange(30.0f);
vehicle->SetTeam(m_object->GetTeam());
CPhysics* physics = vehicle->GetPhysics();
if ( physics != nullptr )

View File

@ -547,8 +547,9 @@ bool CBrain::EventProcess(const Event &event)
axeY = event.motionInput.y;
axeZ = event.motionInput.z;
if ( !m_main->GetTrainerPilot() &&
m_object->GetTrainer() ) // drive vehicle?
if ( (!m_main->GetTrainerPilot() &&
m_object->GetTrainer()) ||
!m_main->CanPlayerInteract() ) // drive vehicle?
{
axeX = 0.0f;
axeY = 0.0f;
@ -1423,7 +1424,7 @@ bool CBrain::CreateInterface(bool bSelect)
type == OBJECT_WORM ||
type == OBJECT_CONTROLLER) // vehicle?
{
if (!(m_main->GetRetroMode()))
if (m_main->GetMissionType() != MISSION_RETRO)
{
ddim.x = dim.x*5.1f;
ddim.y = dim.y*1.5f;
@ -2299,17 +2300,15 @@ void CBrain::UpdateInterface()
type = m_object->GetType();
bEnable = ( m_secondaryTask == 0 && m_currentProgram == nullptr );
bEnable = ( m_primaryTask == 0 && m_currentProgram == nullptr ) && m_main->CanPlayerInteract();
bEnable = ( m_primaryTask == 0 && m_currentProgram == nullptr );
EnableInterface(pw, EVENT_OBJECT_PROGEDIT, (m_primaryTask == 0 && !m_bTraceRecord) && m_selScript < m_program.size());
EnableInterface(pw, EVENT_OBJECT_PROGEDIT, (m_primaryTask == 0 && !m_bTraceRecord) && m_selScript < m_program.size() && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGLIST, bEnable && !m_bTraceRecord);
EnableInterface(pw, EVENT_OBJECT_PROGADD, m_currentProgram == nullptr);
EnableInterface(pw, EVENT_OBJECT_PROGREMOVE, m_currentProgram == nullptr && m_selScript < m_program.size() && !m_program[m_selScript]->readOnly);
EnableInterface(pw, EVENT_OBJECT_PROGCLONE, m_currentProgram == nullptr && m_selScript < m_program.size() && m_program[m_selScript]->runnable);
EnableInterface(pw, EVENT_OBJECT_PROGMOVEUP, m_currentProgram == nullptr && m_program.size() >= 2 && m_selScript > 0);
EnableInterface(pw, EVENT_OBJECT_PROGMOVEDOWN,m_currentProgram == nullptr && m_program.size() >= 2 && m_selScript < m_program.size()-1);
EnableInterface(pw, EVENT_OBJECT_PROGADD, m_currentProgram == nullptr && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGREMOVE, m_currentProgram == nullptr && m_selScript < m_program.size() && !m_program[m_selScript]->readOnly && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGCLONE, m_currentProgram == nullptr && m_selScript < m_program.size() && m_program[m_selScript]->runnable && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGMOVEUP, m_currentProgram == nullptr && m_program.size() >= 2 && m_selScript > 0 && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGMOVEDOWN,m_currentProgram == nullptr && m_program.size() >= 2 && m_selScript < m_program.size()-1 && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_LEFT, bEnable);
EnableInterface(pw, EVENT_OBJECT_RIGHT, bEnable);
EnableInterface(pw, EVENT_OBJECT_UP, bEnable);
@ -2379,8 +2378,8 @@ void CBrain::UpdateInterface()
{
if ( (m_secondaryTask == 0 || !m_secondaryTask->IsBusy()) && m_currentProgram == nullptr )
{
EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0));
EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0));
EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0) && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0) && m_main->CanPlayerInteract());
DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0));
DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0));
}
@ -2404,8 +2403,8 @@ void CBrain::UpdateInterface()
{
if ( m_object->GetFret() != 0 ) bFly = false; // if holder -> not fly
}
EnableInterface(pw, EVENT_OBJECT_GASUP, bFly);
EnableInterface(pw, EVENT_OBJECT_GASDOWN, bFly);
EnableInterface(pw, EVENT_OBJECT_GASUP, bFly && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_GASDOWN, bFly && m_main->CanPlayerInteract());
if ( m_object->GetTrainer() ) // Training?
{
DeadInterface(pw, EVENT_OBJECT_GASUP, false);
@ -2471,7 +2470,7 @@ void CBrain::UpdateInterface()
}
if ( !bEnable && m_currentProgram == nullptr ) bRun = false;
if ( m_bTraceRecord ) bRun = false;
EnableInterface(pw, EVENT_OBJECT_PROGRUN, bRun);
EnableInterface(pw, EVENT_OBJECT_PROGRUN, bRun && m_main->CanPlayerInteract());
pb = static_cast< Ui::CButton* >(pw->SearchControl(EVENT_OBJECT_PROGRUN));
if ( pb != 0 )

View File

@ -958,6 +958,28 @@ Gfx::CameraType CLevelParserParam::AsCameraType(Gfx::CameraType def)
return AsCameraType();
}
MissionType CLevelParserParam::ToMissionType(std::string value)
{
if (value == "NORMAL" ) return MISSION_NORMAL;
if (value == "RETRO" ) return MISSION_RETRO;
if (value == "CODE_BATTLE") return MISSION_CODE_BATTLE;
return static_cast<MissionType>(Cast<int>(value, "MissionType"));
}
MissionType CLevelParserParam::AsMissionType()
{
if (m_empty)
throw CLevelParserExceptionMissingParam(this);
return ToMissionType(m_value);
}
MissionType CLevelParserParam::AsMissionType(MissionType def)
{
if (m_empty)
return def;
return AsMissionType();
}
void CLevelParserParam::ParseArray()
{

View File

@ -34,6 +34,7 @@
#include "object/drive_type.h"
#include "object/object_type.h"
#include "object/tool_type.h"
#include "object/mission_type.h"
#include <string>
#include <vector>
@ -84,6 +85,7 @@ public:
int AsResearchFlag();
Gfx::PyroType AsPyroType();
Gfx::CameraType AsCameraType();
MissionType AsMissionType();
const CLevelParserParamVec& AsArray();
//@}
@ -105,6 +107,7 @@ public:
int AsResearchFlag(int def);
Gfx::PyroType AsPyroType(Gfx::PyroType def);
Gfx::CameraType AsCameraType(Gfx::CameraType def);
MissionType AsMissionType(MissionType def);
//@}
//! Set line this param is part of
@ -133,6 +136,7 @@ private:
int ToResearchFlag(std::string value);
Gfx::PyroType ToPyroType(std::string value);
Gfx::CameraType ToCameraType(std::string value);
MissionType ToMissionType(std::string value);
const std::string FromObjectType(ObjectType value);
const std::string FromCameraType(Gfx::CameraType value);

26
src/object/mission_type.h Normal file
View File

@ -0,0 +1,26 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
*
* 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://gnu.org/licenses
*/
#pragma once
enum MissionType {
MISSION_NORMAL = 0,
MISSION_RETRO,
MISSION_CODE_BATTLE
};

View File

@ -251,6 +251,7 @@ CObject::CObject(int id)
m_magnifyDamage = 1.0f;
m_proxyDistance = 60.0f;
m_param = 0.0f;
m_team = 0;
memset(&m_character, 0, sizeof(m_character));
m_character.wheelFront = 1.0f;
@ -953,6 +954,9 @@ bool CObject::Write(CLevelParserLine* line)
if ( GetMagnifyDamage() != 1.0f )
line->AddParam("magnifyDamage", CLevelParserParamUPtr{new CLevelParserParam(GetMagnifyDamage())});
if ( GetTeam() != 0 )
line->AddParam("team", CLevelParserParamUPtr{new CLevelParserParam(GetTeam())});
if ( GetGunGoalV() != 0.0f )
line->AddParam("aimV", CLevelParserParamUPtr{new CLevelParserParam(GetGunGoalV())});
@ -1048,6 +1052,7 @@ bool CObject::Read(CLevelParserLine* line)
SetProxyDistance(line->GetParam("proxyDistance")->AsFloat(15.0f)*g_unit);
SetRange(line->GetParam("range")->AsFloat(30.0f));
SetMagnifyDamage(line->GetParam("magnifyDamage")->AsFloat(1.0f));
SetTeam(line->GetParam("team")->AsInt(0));
SetGunGoalV(line->GetParam("aimV")->AsFloat(0.0f));
SetGunGoalH(line->GetParam("aimH")->AsFloat(0.0f));
SetParam(line->GetParam("param")->AsFloat(0.0f));
@ -2815,6 +2820,18 @@ bool CObject::GetClip()
}
// Controls object team
void CObject::SetTeam(int team)
{
m_team = team;
}
int CObject::GetTeam()
{
return m_team;
}
// Pushes an object.
@ -3379,7 +3396,7 @@ void CObject::CreateSelectParticle()
}
}
if ( m_bSelect || IsProgram() || m_main->GetRetroMode() )
if ( m_bSelect || IsProgram() || m_main->GetMissionType() == MISSION_RETRO )
{
// Creates particles lens for the headlights.
if ( m_type == OBJECT_MOBILEfa ||
@ -3433,7 +3450,7 @@ void CObject::UpdateSelectParticle()
float angle;
int i;
if ( !m_bSelect && !IsProgram() && !m_main->GetRetroMode() ) return;
if ( !m_bSelect && !IsProgram() && m_main->GetMissionType() != MISSION_RETRO ) return;
dim[0].x = 1.0f;
dim[1].x = 1.0f;
@ -3557,7 +3574,7 @@ void CObject::UpdateSelectParticle()
zoom[3] = 1.0f;
if ( ( IsProgram() || // current program?
m_main->GetRetroMode() ) && // Retro mode?
m_main->GetMissionType() == MISSION_RETRO ) && // Retro mode?
Math::Mod(m_aTime, 0.7f) < 0.3f )
{
zoom[0] = 0.0f; // blinks
@ -3663,6 +3680,9 @@ int CObject::GetDefRank()
bool CObject::GetTooltipName(std::string& name)
{
GetResource(RES_OBJECT, m_type, name);
if(GetTeam() != 0) {
name += " [team "+boost::lexical_cast<std::string>(GetTeam())+"]"; //TODO: better way to display this
}
return !name.empty();
}

View File

@ -278,6 +278,9 @@ public:
void SetClip(bool bClip);
bool GetClip();
void SetTeam(int team);
int GetTeam();
bool JostleObject(float force);
void StartDetectEffect(CObject *target, bool bFound);
@ -468,6 +471,7 @@ protected:
float m_magnifyDamage;
float m_proxyDistance;
float m_param;
int m_team;
int m_crashSphereUsed; // number of spheres used
Math::Vector m_crashSpherePos[MAXCRASHSPHERE];

View File

@ -130,6 +130,19 @@ CObject* CObjectManager::CreateObject(Math::Vector pos,
return objectPtr;
}
std::vector<CObject*> CObjectManager::GetObjectsOfTeam(int team)
{
std::vector<CObject*> result;
for (CObject* object : GetAllObjects())
{
if (object->GetTeam() == team)
{
result.push_back(object);
}
}
return result;
}
CObject* CObjectManager::Radar(CObject* pThis, ObjectType type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes)
{
std::vector<ObjectType> types;

View File

@ -145,6 +145,9 @@ public:
//! Gets object by id in range <0; number of objects - 1>
CObject* GetObjectByRank(unsigned int id);
//! Gets all objects of given team
std::vector<CObject*> GetObjectsOfTeam(int team);
//! Returns all objects
inline CObjectContainerProxy GetAllObjects()
{

View File

@ -175,7 +175,7 @@ CRobotMain::CRobotMain(CController* controller)
m_infoUsed = 0;
m_controller = nullptr;
m_retroStyle = false;
m_missionType = MISSION_NORMAL;
m_immediatSatCom = false;
m_beginSatCom = false;
m_lockedSatCom = false;
@ -188,6 +188,9 @@ CRobotMain::CRobotMain(CController* controller)
m_selectInsect = false;
m_showSoluce = false;
m_codeBattleInit = false;
m_codeBattleStarted = false;
#if DEV_BUILD
m_showAll = true; // for development
#else
@ -1871,7 +1874,7 @@ bool CRobotMain::SelectObject(CObject* obj, bool displayError)
if (m_camera->GetType() == Gfx::CAM_TYPE_VISIT)
StopDisplayVisit();
if (m_movieLock || m_editLock || m_pause->GetPause()) return false;
if (m_movieLock || m_editLock) return false;
if (m_movie->IsExist()) return false;
if (obj == nullptr || !IsSelectable(obj)) return false;
@ -2695,7 +2698,7 @@ bool CRobotMain::EventFrame(const Event &event)
{
dim.x = 32.0f/640.0f;
dim.y = 32.0f/480.0f;
pos.x = 20.0f/640.0f;
pos.x = (640.0f-24.0f)/640.0f;
pos.y = (480.0f-24.0f)/480.0f;
float zoom = 1.0f+sinf(m_time*6.0f)*0.1f; // 0.9 .. 1.1
@ -2758,6 +2761,17 @@ bool CRobotMain::EventFrame(const Event &event)
}
}
if(!m_codeBattleInit) {
// NOTE: It's important to do this AFTER the first update event finished processing
// because otherwise all robot parts are misplaced
ChangePause(PAUSE_USER);
m_codeBattleInit = true; // Will start on resume
}
if(!m_codeBattleStarted && m_pause->GetPause() == PAUSE_NONE) {
m_codeBattleStarted = true;
m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE));
}
return true;
}
@ -2920,9 +2934,11 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
strcpy(m_scriptName, scriptNameStr.c_str());
m_scriptFile[0] = 0;
m_retroStyle = false;
m_missionType = MISSION_NORMAL;
m_codeBattleInit = false;
m_codeBattleStarted = false;
m_missionResult = ERR_MISSION_NOTERM;
m_missionResult = ERR_MISSION_NOTERM;
}
//NOTE: Reset timer always, even when only resetting object positions
@ -3228,8 +3244,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_engine->SetTracePrecision(line->GetParam("traceQuality")->AsFloat(1.0f));
m_shortCut = line->GetParam("shortcut")->AsBool(true);
m_retroStyle = line->GetParam("retro")->AsBool(false);
if (m_retroStyle) GetLogger()->Info("Retro mode enabled.\n");
m_missionType = line->GetParam("type")->AsMissionType(MISSION_NORMAL);
continue;
}
@ -3570,6 +3585,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
obj->SetRange(line->GetParam("range")->AsFloat(30.0f));
obj->SetShield(line->GetParam("shield")->AsFloat(1.0f));
obj->SetMagnifyDamage(line->GetParam("magnifyDamage")->AsFloat(1.0f));
obj->SetTeam(line->GetParam("team")->AsInt(0));
obj->SetClip(line->GetParam("clip")->AsBool(true));
obj->SetCheckToken(!line->GetParam("checkToken")->IsDefined() ? trainer || !selectable : line->GetParam("checkToken")->AsBool(true));
// SetManual will affect bot speed
@ -5862,9 +5878,9 @@ const char* CRobotMain::GetFilesDir()
return m_dialog->GetFilesDir().c_str();
}
bool CRobotMain::GetRetroMode()
MissionType CRobotMain::GetMissionType()
{
return m_retroStyle;
return m_missionType;
}
//! Change the player's name
@ -6277,3 +6293,11 @@ void CRobotMain::SetExitAfterMission(bool exit)
{
m_exitAfterMission = exit;
}
bool CRobotMain::CanPlayerInteract()
{
if(GetMissionType() == MISSION_CODE_BATTLE) {
return !m_codeBattleStarted;
}
return true;
}

View File

@ -34,6 +34,7 @@
#include "object/drive_type.h"
#include "object/tool_type.h"
#include "object/mainmovie.h"
#include "object/mission_type.h"
#include "app/pausemanager.h"
@ -287,7 +288,7 @@ public:
const char* GetSavegameDir();
const char* GetPublicDir();
const char* GetFilesDir();
bool GetRetroMode();
MissionType GetMissionType();
void SetGamerName(const char *name);
char* GetGamerName();
@ -358,6 +359,9 @@ public:
//! Enable mode where completing mission closes the game
void SetExitAfterMission(bool exit);
//! Returns true if player can interact with things manually
bool CanPlayerInteract();
protected:
bool EventFrame(const Event &event);
bool EventObject(const Event &event);
@ -452,7 +456,7 @@ protected:
CObject* m_controller;
bool m_retroStyle; // Retro
MissionType m_missionType;
bool m_immediatSatCom; // SatCom immediately?
bool m_beginSatCom; // messages SatCom poster?
bool m_lockedSatCom; // SatCom locked?
@ -489,6 +493,9 @@ protected:
bool m_exitAfterMission;
bool m_codeBattleInit;
bool m_codeBattleStarted;
float m_fontSize;
Math::Point m_windowPos;
Math::Point m_windowDim;

View File

@ -82,6 +82,7 @@ bool CTaskBuild::CreateBuilding(Math::Vector pos, float angle)
m_building = CObjectManager::GetInstancePointer()->CreateObject(pos, angle, m_type, power);
m_building->UpdateMapping();
m_building->SetLock(true); // not yet usable
m_building->SetTeam(m_object->GetTeam());
if ( m_type == OBJECT_DERRICK ) m_buildingHeight = 35.0f;
if ( m_type == OBJECT_FACTORY ) m_buildingHeight = 28.0f;

View File

@ -127,7 +127,8 @@ bool CMainShort::CreateShortcuts()
m_engine->GetPause()) ) // hangs during edition?
{
m_interface->CreateShortcut(pos, dim, 6, EVENT_OBJECT_EDITLOCK);
return true;
if(!m_engine->GetPause())
return true;
}
rank = 0;