cyphesis/rulesets/BaseMind.cpp
Al Riddoch 2ccfaadef3 2001-04-14 Al Riddoch <alriddoch@zepler.org>
* Substantial re-work of object model. Moved many attributes out
	  of BaseEntity class. Changed WoldRouter so it now handles
	  objects in terms of Entity, rather than BaseEntity.

	* Code cleanups, including removing reduntant includes, and
	  getting rid of C style comments.

	* Fixed the way attributes are handled in Set operations and
	  when merging from an Atlas::Message::Object. This fixed
	  problem with setting gender of characters.

	* rulesets/Pedestrian.*, rulesets/Movement.*: Re-named
	  Movement variables to make them clearer. Added in
	  separate handling for collisions from moving to
	  target position. Modified collision handling so
	  objects can slide next to each other.

	* rulesets/Thing.cpp, rulesets/Character.cpp: Cleaned up and
	  rationalised movement code. Much shorter, faster and
	  more compact than before.

	* Made better use of iterators throughout, eliminating unnecessary
	  lookups, and copying of data.

	* Moved all virtual functions out of header files, making
	  less work for the linker.

	* Made more use of const references to avoid the need to copy
	  data before being able to inspect it.

Al Riddoch <alriddoch@zepler.org>
2001-04-16 16:26:44 +00:00

387 lines
10 KiB
C++

// This file may be redistributed and modified only under the terms of
// the GNU General Public License (See COPYING for details).
// Copyright (C) 2000,2001 Alistair Riddoch
#include <Atlas/Message/Object.h>
#include <Atlas/Objects/Root.h>
#include <Atlas/Objects/Entity/RootEntity.h>
#include <Atlas/Objects/Operation/Login.h>
#include <Atlas/Objects/Operation/Sight.h>
#include <Atlas/Objects/Operation/Sound.h>
#include <Atlas/Objects/Operation/Combine.h>
#include <Atlas/Objects/Operation/Create.h>
#include <Atlas/Objects/Operation/Delete.h>
#include <Atlas/Objects/Operation/Divide.h>
#include <Atlas/Objects/Operation/Move.h>
#include <Atlas/Objects/Operation/Set.h>
#include <Atlas/Objects/Operation/Talk.h>
#include <Atlas/Objects/Operation/Touch.h>
#include <Atlas/Objects/Operation/Appearance.h>
#include <Atlas/Objects/Operation/Disappearance.h>
#include <common/Chop.h>
#include <common/Cut.h>
#include <common/Eat.h>
#include <common/Fire.h>
#include <common/utility.h>
#include <common/debug.h>
#include <common/op_switch.h>
#include "BaseMind.h"
#include "MemMap_methods.h"
//static const bool debug_flag = false;
BaseMind::BaseMind(const string & id, const string & body_name) : map(script)
{
//map=MemMap();
fullid = id;
name = body_name;
map.addObject(this);
//BaseMind::time=WorldTime();
//if (const.debug_level>=1) {
//BaseMind::log_fp=open("mind_"+BaseMind::id+".log","w");
//}
//else {
//BaseMind::log_fp=NULL;
//}
}
BaseMind::~BaseMind()
{
}
MemMap * BaseMind::getMap() {
return &map;
}
oplist BaseMind::sightOperation(const Sight & op, Login & sub_op)
{
oplist res;
if (script->Operation("sight_login", op, res, &sub_op) != 0) {
return(res);
}
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Chop & sub_op)
{
oplist res;
script->Operation("sight_chop", op, res, &sub_op);
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Create & sub_op)
{
oplist res;
if (script->Operation("sight_create", op, res, &sub_op) != 0) {
return(res);
}
const Object::ListType & args = sub_op.GetArgs();
if (args.size() == 0) {
debug( cout << " no args!" << endl << flush;);
return(res);
}
Object obj = args.front();
Root * arg = utility::Object_asRoot(obj);
if (arg->GetObjtype() != "op") {
map.add(arg->AsObject());
}
delete arg;
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Cut & sub_op)
{
oplist res;
script->Operation("sight_cut", op, res, &sub_op);
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Delete & sub_op)
{
debug( cout << "Sight Delete operation" << endl << flush;);
oplist res;
if (script->Operation("sight_delete", op, res, &sub_op) != 0) {
return(res);
}
const Object::ListType & args = sub_op.GetArgs();
if (args.size() == 0) {
debug( cout << " no args!" << endl << flush;);
return(res);
}
Object obj = args.front();
if (obj.IsString()) {
map.del(obj.AsString());
} else {
Root * arg = utility::Object_asRoot(obj);
if (arg->GetObjtype() != "op") {
map.del(arg->GetId());
}
delete arg;
}
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Eat & sub_op)
{
oplist res;
script->Operation("sight_eat", op, res, &sub_op);
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Fire & sub_op)
{
oplist res;
script->Operation("sight_fire", op, res, &sub_op);
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Move & sub_op)
{
debug( cout << "BaseMind::sightOperation(Sight, Move)" << endl << flush;);
oplist res;
if (script->Operation("sight_move", op, res, &sub_op) != 0) {
return(res);
}
const Object::ListType & args = sub_op.GetArgs();
if (args.size() == 0) {
debug( cout << " no args!" << endl << flush;);
return(res);
}
const Object & obj = args.front();
Root * arg = utility::Object_asRoot(obj);
if (arg->GetObjtype() != "op") {
map.update(obj);
}
delete arg;
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Set & sub_op)
{
oplist res;
if (script->Operation("sight_set", op, res, &sub_op) != 0) {
return(res);
}
const Object::ListType & args = sub_op.GetArgs();
if (args.size() == 0) {
debug( cout << " no args!" << endl << flush;);
return(res);
}
const Object & obj = args.front();
Root * arg = utility::Object_asRoot(obj);
if (arg->GetObjtype() != "op") {
map.update(obj);
}
delete arg;
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, Touch & sub_op)
{
oplist res;
script->Operation("sight_touch", op, res, &sub_op);
return(res);
}
oplist BaseMind::sightOperation(const Sight & op, RootOperation & sub_op)
{
debug( cout << "BaseMind::sightOperation(Sight, RootOperation)" << endl << flush;);
oplist res;
script->Operation("sight_undefined", op, res, &sub_op);
return(res);
}
oplist BaseMind::soundOperation(const Sound & op, Talk & sub_op)
{
debug( cout << "BaseMind::soundOperation(Sound, Talk)" << endl << flush;);
oplist res;
script->Operation("sound_talk", op, res, &sub_op);
return(res);
}
oplist BaseMind::soundOperation(const Sound & op, RootOperation & sub_op)
{
debug( cout << "BaseMind::soundOperation(Sound, RootOperation)" << endl << flush;);
oplist res;
script->Operation("sound_undefined", op, res, &sub_op);
return(res);
}
oplist BaseMind::Operation(const Sound & op)
{
// Deliver argument to sound things
oplist res;
if (script->Operation("sound", op, res) != 0) {
return(res);
}
const Object::ListType & args = op.GetArgs();
if (args.size() == 0) {
debug( cout << " no args!" << endl << flush;);
return(res);
}
Object obj = args.front();
Root * op2 = utility::Object_asRoot(obj);
if (op2->GetObjtype() == "op") {
debug( cout << " args is an op!" << endl << flush;);
res = callSoundOperation(op, *(RootOperation *)op2);
}
delete op2;
return(res);
}
oplist BaseMind::Operation(const Sight & op)
{
debug( cout << "BaseMind::Operation(Sight)" << endl << flush;);
// Deliver argument to sight things
oplist(res);
if (script->Operation("sight", op, res) != 0) {
debug( cout << " its in the script" << endl << flush;);
return(res);
}
const Object::ListType & args = op.GetArgs();
if (args.size() == 0) {
debug( cout << " no args!" << endl << flush;);
return(res);
}
Object obj = args.front();
Root * op2 = utility::Object_asRoot(obj);
if (op2->GetObjtype() == "op") {
debug( cout << " args is an op!" << endl << flush;);
res = callSightOperation(op, *(RootOperation *)op2);
//string & op2type = op2->GetParents().front().AsString();
//string subop = "sight_" + op2type;
//script->Operation(subop, op, res, (RootOperation *)op2);
} else /* if (op2->GetObjtype() == "object") */ {
debug( cout << " arg is an entity!" << endl << flush;);
map.add(obj);
}
delete op2;
return(res);
}
oplist BaseMind::Operation(const Appearance & op)
{
oplist(res);
script->Operation("appearance", op, res);
const Object::ListType & args = op.GetArgs();
Object::ListType::const_iterator I;
for(I = args.begin(); I != args.end(); I++) {
map.getAdd(I->AsMap().find("id")->second.AsString());
}
return res;
}
oplist BaseMind::Operation(const Disappearance & op)
{
oplist(res);
script->Operation("disappearance", op, res);
// Not quite sure what to do to the map here, but should do something.
return res;
}
#if 0
RootOperation * BaseMind::get_op_name_and_sub(RootOperation & op, string & name)
{
event_name = op.id;
sub_op = op;
while (len(sub_op) and sub_op[0].get_name()=="op") {
sub_op = sub_op[0];
event_name = event_name + "_" + sub_op.id;
}
return event_name, sub_op;
}
int BaseMind::call_triggers(RootOperation & op)
{
return(0);
}
#endif
//oplist BaseMind::message(const RootOperation & msg)
//{
//return operation(msg);
//}
oplist BaseMind::operation(const RootOperation & op)
{
// This might end up being quite tricky to do
// In the python the following happens here:
// Find out if the op refers to any ids we don't know about.
// If so create look operations to those ids
// Set the minds time and date
oplist res;
map.getAdd(op.GetFrom());
RootOperation * look;
while ((look = map.lookId()) != NULL) {
res.push_back(look);
}
oplist res2 = callOperation(op);
for(oplist::const_iterator I = res2.begin(); I != res2.end(); I++) {
res.push_back(*I);
}
//res = call_triggers(op);
return(res);
}
oplist BaseMind::callSightOperation(const Sight& op, RootOperation& sub_op) {
map.getAdd(sub_op.GetFrom());
op_no_t op_no = opEnumerate(sub_op);
SUB_OP_SWITCH(op, op_no, sight, sub_op)
}
oplist BaseMind::callSoundOperation(const Sound& op, RootOperation& sub_op) {
map.getAdd(sub_op.GetFrom());
op_no_t op_no = opEnumerate(sub_op);
SUB_OP_SWITCH(op, op_no, sound, sub_op)
}
#if 0
oplist BaseMind::operation(const RootOperation & op)
{
if (hasattr(this,"lock")) {
return;
}
if (BaseMind::log_fp) {
BaseMind::log_fp.write("receiving:\n");
BaseMind::log_fp.write(str(op)+"\n");
}
reply=Message();
res=op.atlas2internal(BaseMind::map.things);
if (res) {
log.debug(3,str(BaseMind::id)+" : new id: "+str(res));
for (/*(err_op,attr,id) in res*/) {
obj=BaseMind::map.add_id(id);
if (type(err_op)==InstanceType) {
setattr(err_op,attr,obj);
}
else {
err_op[attr]=obj;
}
log.debug(3,str(obj));
}
}
while (1) {
look=BaseMind::map.look_id();
if (not look) {
break;
}
look.from_=this;
reply.append(look);
}
if (hasattr(op.time,"dateTime")) {
BaseMind::time=op.time.dateTime;
}
reply=reply+BaseMind::call_operation(op);
reply=reply+BaseMind::call_triggers(op);
op.internal2atlas();
if (BaseMind::log_fp) {
BaseMind::log_fp.write("sending:\n");
BaseMind::log_fp.write(str(reply)+"\n");
}
return reply;
}
#endif