07-07-2015, 09:35 PM
(This post was last modified: 07-07-2015, 09:36 PM by krzys_h.
Edit Reason: Added example program
)
Recently I started working on a completly new gamemode - code battles. The idea is that you set up two programs to fight with each other. The player can't interact with the world manually. See the related issue on GitHub - https://github.com/colobot/colobot/issues/468
This thread was created to document all features that are needed to create and play code battle levels.
I. Code battle gamemode
Enabled in scene file like so:
What does this do? It sets up everything for a code battle level - makes the level start paused in order to configure programs, and disables user interaction with the world. After starting the level, you can't even stop the program.
This is still work in progress, some user interaction is still possible
II. Support for teams in scene files
a) CreateObject
The way the teams work is really simple - you specify a team for a robot in scene file, and that setting propagates to all buildings and robots created by that object. Value 0 is the default meaning "no team assigned".
You specify the team in CreateObject, like so:
b) EndMissionTake team=X
This filters results of EndMissionTake to the specific team, just like every other EndMissionTake parameter does.
Example:
c) EndMissionTake team=-X
Negative value for team parameter means "match everything except for team X and objects with no team assigned". Example:
d) EndMissionTake winTeam=X
This one is a bit more complicated. It's easiest to describe like that: "If this condition would mean the mission is won, then team X wins the whole game. If this condition would mean the mission is lost, this team is eliminated from the gameplay and all it's objects are automatically destroyed"
Example:
e) TeamName team=X name="YYYYY"
This sets the name of the team that is displayed in the tooltip. Example:
f) VehicleColor team=X color=R;G;B;A
NOT IMPLEMENTED YET!
This is an extension to VehicleColor command allowing to make objects of diffrent teams have diffrent colors.
Example:
III. Support for teams in CBOT
a) object.team
Returns the team this object is on. Example:
b) radar() - enhancement for filters
Do you remember the undocumented FilterOnly* parameter? Now you can also use it to detect only friends, enemies and objects on given team. You can use bitwise OR (|) to combine diffrent filters.
Some examples:
As you can see, there are lots of possible combinations you can do.
c) Any
A little bonus, a nice constant Any can be used instead of 0 in radar() to detect any object (including decorative objects, that might be changed later)
As you can see, lots of new features were (or will be) added to make this possible. I'll try to make an example level soon. I'm waiting for comments on this and hoping that this will make the community wake up and do something, as well as attract some new players to Colobot.
EDIT: Added example level, as promised:
CodeBattle.zip (Size: 2.8 KB / Downloads: 427)
EDIT: And a VERY basic solution:
This thread was created to document all features that are needed to create and play code battle levels.
I. Code battle gamemode
Enabled in scene file like so:
Code:
Mission type=CODE_BATTLE
This is still work in progress, some user interaction is still possible
II. Support for teams in scene files
a) CreateObject
The way the teams work is really simple - you specify a team for a robot in scene file, and that setting propagates to all buildings and robots created by that object. Value 0 is the default meaning "no team assigned".
You specify the team in CreateObject, like so:
Code:
CreateObject pos=0;-10 dir=1.5 type=WheeledGrabber team=1 select=1
CreateObject pos=0;10 dir=0.5 type=WheeledGrabber team=2
b) EndMissionTake team=X
This filters results of EndMissionTake to the specific team, just like every other EndMissionTake parameter does.
Example:
Code:
EndMissionTake pos=0;0 dist=10000 type=Any team=1 min=0 max=0 // Mission complete when all team 1 objects are destroyed
c) EndMissionTake team=-X
Negative value for team parameter means "match everything except for team X and objects with no team assigned". Example:
Code:
EndMissionTake pos=0;0 dist=10000 type=Any team=-1 min=0 max=0 // Mission complete when all objects from teams OTHER than 1 are destroyed (excluding objects with no team)
d) EndMissionTake winTeam=X
This one is a bit more complicated. It's easiest to describe like that: "If this condition would mean the mission is won, then team X wins the whole game. If this condition would mean the mission is lost, this team is eliminated from the gameplay and all it's objects are automatically destroyed"
Example:
Code:
// The team that destroys all enemy objects wins the game
EndMissionTake pos=0;0 dist=10000 type=Any team=-1 min=0 max=0 winTeam=1
EndMissionTake pos=0;0 dist=10000 type=Any team=-2 min=0 max=0 winTeam=2
e) TeamName team=X name="YYYYY"
This sets the name of the team that is displayed in the tooltip. Example:
Code:
TeamName team=1 name="Red"
TeamName team=2 name="Blue"
f) VehicleColor team=X color=R;G;B;A
NOT IMPLEMENTED YET!
This is an extension to VehicleColor command allowing to make objects of diffrent teams have diffrent colors.
Example:
Code:
VehicleColor color=0;1;0;0 // Default color, used for objects without team or if team color is not defined
VehicleColor team=1 color=1;0;0;0 // "Red" team
VehicleColor team=2 color=0;0;1;0 // "Blue" team
III. Support for teams in CBOT
a) object.team
Returns the team this object is on. Example:
Code:
object item = radar(WheeledGrabber);
if(item.team == this.team) message("We are friends");
else message("We are enemies");
b) radar() - enhancement for filters
Do you remember the undocumented FilterOnly* parameter? Now you can also use it to detect only friends, enemies and objects on given team. You can use bitwise OR (|) to combine diffrent filters.
Some examples:
Code:
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterNone); // default, any object
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterOnlyLanding); // this is old but undocumented, used in AlienWasp code, radars only objects that are not currently flying
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterOnlyFlying); // reverse of the above, for some reason there was a typo in the code and earlier it was actually named FilterOnlyFliying
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterFriendly); // only friendly objects (objects on the same team)
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterEnemy); // only enemy objects (objects on diffrent team)
radar(WheeledGrabber, 0, 360, 0, 1000, 1, 1); // only objects on team 1
radar(WheeledGrabber, 0, 360, 0, 1000, 1, 7); // only objects on team 7
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterNeutral); // only neutral objects (objects with no team assigned) - DO NOT USE TEAM ID 0 INSTEAD OF FilterNeutral, it won't work
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterFriendly | FilterEnemy); // all friendly and enemy objects, reverse of the above
radar(WheeledGrabber, 0, 360, 0, 1000, 1, FilterFriendly | FilterOnlyFlying); // all friendly objects that are currently flying
radar(WheeledGrabber, 0, 360, 0, 1000, 1, 2 | FilterOnlyLanding); // objects from team 2 that are not currently flying
radar(WheeledGrabber, 0, 360, 0, 1000, 1, 1 | 2 | 3); // THIS IS WRONG, DON'T DO THIS - you can only specify only ONE team number at once
c) Any
A little bonus, a nice constant Any can be used instead of 0 in radar() to detect any object (including decorative objects, that might be changed later)
Code:
object item = radar(Any);
As you can see, lots of new features were (or will be) added to make this possible. I'll try to make an example level soon. I'm waiting for comments on this and hoping that this will make the community wake up and do something, as well as attract some new players to Colobot.
EDIT: Added example level, as promised:
CodeBattle.zip (Size: 2.8 KB / Downloads: 427)
EDIT: And a VERY basic solution:
Code:
void GetTitanium()
{
object item;
item = radar(TitaniumOre);
goto(item.position);
grab();
item = radar(Converter, 0, 360, 0, 1000, 1, FilterFriendly);
goto(item.position);
drop();
move(-2.5);
while((item = radar(Titanium, 0, 45, 0, 10)) == null) wait(0.1);
goto(item.position);
grab();
}
void object::Build(int cat)
{
GetTitanium();
goto(space(this.position, 8, 50, 15));
drop();
build(cat);
}
void GetCell()
{
GetTitanium();
object item = radar(PowerPlant, 0, 360, 0, 1000, 1, FilterFriendly);
goto(item.position);
drop();
while(item.energyCell.category != PowerCell) wait(0.1);
grab();
}
void Research(int cat)
{
GetCell();
object item = radar(ResearchCenter, 0, 360, 0, 1000, 1, FilterFriendly);
goto(item.position);
drop();
item.research(cat);
//while(item.busy()) wait(0.1);
}
object object::Factory(int cat, string program)
{
GetTitanium();
object item = radar(BotFactory, 0, 360, 0, 1000, 1, FilterFriendly);
goto(item.position);
drop();
move(-5);
item.factory(cat, program);
point start_pos = this.position;
GetCell();
goto(start_pos);
turn(direction(item.position));
while(item.busy()) wait(0.1);
item = radar(cat, 0, 360, 0, 1000, 1, FilterFriendly);
goto(item.position);
drop();
move(-10);
return item;
}
extern void object::KrzysHCodeBattleTestProgram()
{
object item;
item = radar(Titanium);
goto(item.position);
build(Converter);
Build(PowerPlant);
Build(ResearchCenter);
Research(ResearchShooter);
Build(BotFactory);
item = Factory(WheeledShooter, progfunc("Shooter"));
camerafocus(item);
}
public void object::Shooter()
{
while(this.energyCell == null) continue;
wait(2);
move(-5);
while(true) {
object item = radar(Any, 0, 360, 0, 1000, 1, FilterEnemy);
if(item == null) return;
turn(direction(item.position));
move(distance(this.position, item.position)-30);
fire(1);
}
}