#include "gameobjs.h" #include #include "engine.h" /** * \file vm_interface.cpp * methods responsible for converting native gameobjects to those recognizable * by the virtual machines */ using namespace BMD; using BMD::Value; Value Engine::construct_vm_input(int bomber_id) const { // construct the bomber list vector bomber_list; for (unsigned int i = 0; i < bombers.size(); ++i) bomber_list.push_back(bombers[i].to_value()); ListRef vm_bombers = List::from_vector(bomber_list); // bomb list vector bomb_list; for (unsigned int i = 0; i < bombs.size(); ++i) bomb_list.push_back(bombs[i].to_value(bomber_id)); ListRef vm_bombs = List::from_vector(bomb_list); // powerup list vector powerup_list; for (unsigned int i = 0; i < powerups.size(); ++i) powerup_list.push_back(powerups[i].to_value()); ListRef vm_powerups = List::from_vector(powerup_list); // tile 2D array int height = stage.getH(); int width = stage.getW(); BlockRef tiles(new Block(width, Block::Array)); for (int i = 0; i < width; ++i) { BlockRef col(new Block(height, Block::Array)); tiles->set_elem(i, Value(col)); for (int j = 0; j < height; ++j) { col->set_elem(j, Value(to_vm_tile(stage.tile_tinfo(Coordinates(i, j))))); } } // bomber status Value bomber_status = bombers[bomber_id].status_value(); // create the input vector vm_input_fields; vm_input_fields.push_back(tiles); vm_input_fields.push_back(vm_bombers); vm_input_fields.push_back(vm_bombs); vm_input_fields.push_back(vm_powerups); vm_input_fields.push_back(bomber_status); return BlockRef(new Block(vm_input_fields, Block::Struct)); } BomberOrders::BomberOrders(Value v) { bomb_place = false; detonate = false; move_direction = dVOID; BlockRef b; try { b = v.get_struct(); if (b->get_size() != 3) return; bomb_place = (bool)b->get_elem(0).get_int(); detonate = (bool)b->get_elem(1).get_int(); move_direction = from_vm_direction(b->get_elem(2).get_int()); } catch (...) { cerr << "improper bomber move return, returned: " << endl; v.print(cerr, true); } } Value Coordinates::to_value() const { BlockRef bl(new Block(2, Block::Struct)); bl->set_elem(0, Value((int)x)); bl->set_elem(1, Value((int)y)); return bl; } Value Bomb::to_value(int bomber_id) const { vector fields; // position fields.push_back( coords.to_value() ); // is_mine fields.push_back( Value( bomber_id == get_owner_id() ) ); // direction int dir = mstate.get_direction(); fields.push_back( Value( dir ) ); return Value(BlockRef(new Block(fields, Block::Struct))); } Value Bomber::to_value() const { vector fields; // position fields.push_back( coords.to_value() ); // id fields.push_back( Value( (int) id ) ); // team id fields.push_back( Value( (int) team_id ) ); return Value(BlockRef(new Block(fields, Block::Struct))); } Value PowerUp::to_value() const { vector fields; // position fields.push_back( coords.to_value() ); // power up type fields.push_back( Value( (int) to_vm_powerup(power_type_index)) ); return Value(BlockRef(new Block(fields, Block::Struct))); } Value Bomber::status_value() const { // status vector status_fields; // position status_fields.push_back(coords.to_value()); // id status_fields.push_back(Value((int)id)); // team id status_fields.push_back(Value((int)team_id)); // move rate status_fields.push_back(Value(to_vm_movespeed(prop.move_steps))); // has kick status_fields.push_back(Value(prop.kicking)); // has detonate status_fields.push_back(Value(prop.detonation)); // radius status_fields.push_back(Value((int)bomb_prop.power)); // max bombs status_fields.push_back(Value((int)prop.max_bombs)); // deployed bombs status_fields.push_back(Value((int)nbombs)); return BlockRef(new Block(status_fields, Block::Struct)); } int to_vm_powerup(int power_up) { return power_up + 1; } int to_vm_direction(int direction) { switch (direction) { case dNORTH: return 1; case dEAST: return 2; case dSOUTH: return 3; case dWEST: return 4; default: return 0; } } int from_vm_direction(int vm_dir) { switch (vm_dir) { case 1: return dNORTH; case 2: return dEAST; case 3: return dSOUTH; case 4: return dWEST; default: return 0; } } int to_vm_tile(int tile) { return tile + 1; }