Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 06-13-2010, 04:04 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default COMMITTED: Ported Objects to Perl

Ported objects to perl today. You can now get an object list via perl with $entity_list->GetObjectList(), and do a lot of things with them, all from perl. This was just me experimenting with the perlxs util in the utilities folder, but it evolved into this.

Check below where it boots up for a list of perl commands. I handpicked the functions that could prove useful.

Image:



Example Script:

Code:
sub EVENT_SAY { 
if($text=~/object/i)
	    {
	            my @moblist = $entity_list->GetObjectList();
	            foreach $ent (@moblist)
	            {
	                    quest::ze(15, $ent->GetDBID())
	            }
	    }

}
Diff:

Code:
Index: doors.cpp
===================================================================
--- doors.cpp	(revision 1556)
+++ doors.cpp	(working copy)
@@ -599,9 +599,4 @@
 		return false;
 	}
 	return true;
-}
-
-
-
-
-
+}
\ No newline at end of file
Index: embperl.cpp
===================================================================
--- embperl.cpp	(revision 1556)
+++ embperl.cpp	(working copy)
@@ -38,6 +38,7 @@
 EXTERN_C XS(boot_Raid);
 EXTERN_C XS(boot_QuestItem);
 EXTERN_C XS(boot_HateEntry);
+EXTERN_C XS(boot_Object);
 EXTERN_C XS(boot_PerlPacket);
 /*XS(XS_Client_new);
 //XS(XS_Mob_new);
@@ -88,6 +89,7 @@
 	newXS(strcpy(buf, "Raid::boot_Raid"), boot_Raid, file);
 	newXS(strcpy(buf, "QuestItem::boot_QuestItem"), boot_QuestItem, file);
 	newXS(strcpy(buf, "HateEntry::boot_HateEntry"), boot_HateEntry, file);
+	newXS(strcpy(buf, "Object::boot_Object"), boot_Object, file);
 ;
 #endif
 #endif
Index: entity.cpp
===================================================================
--- entity.cpp	(revision 1556)
+++ entity.cpp	(working copy)
@@ -1000,6 +1000,40 @@
 	return 0;
 }
 
+Object* EntityList::GetObjectByDBID(int32 id) {
+	LinkedListIterator<Object*> iterator(object_list);
+
+	iterator.Reset();
+	while(iterator.MoreElements())
+	{
+		if (iterator.GetData())
+		{
+			if (iterator.GetData()->CastToObject()->GetDBID() == id) {
+				return iterator.GetData();
+			}
+		}
+		iterator.Advance();
+	}
+	return 0;
+}
+
+Object* EntityList::GetObjectByID(int16 id) {
+	LinkedListIterator<Object*> iterator(object_list);
+
+	iterator.Reset();
+	while(iterator.MoreElements())
+	{
+		if (iterator.GetData())
+		{
+			if (iterator.GetData()->CastToObject()->GetID() == id) {
+				return iterator.GetData();
+			}
+		}
+		iterator.Advance();
+	}
+	return 0;
+}
+
 NPC* EntityList::GetNPCByNPCTypeID(int32 npc_id)
 {
 	if (npc_id == 0)
@@ -3833,7 +3867,7 @@
 	} 
 }
 
-void EntityList::CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time)
+int16 EntityList::CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time)
 {
 	const Item_Struct* is = database.GetItem(itemid);
 	if(is)
@@ -3845,10 +3879,28 @@
 			entity_list.AddObject(object, true);
 			object->StartDecay();
 			safe_delete(i);
+			if(object)
+			return object->GetID();
 		}
+		return 0; // fell through itemstruct
 	}
+	return 0; // fell through everything, this is bad/incomplete from perl
 }
 
+int16 EntityList::CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, int8 type)
+{
+	if(model)
+	{
+			Object* object = new Object(model,x,y,z,heading,type);
+			entity_list.AddObject(object, true);
+			//object->StartDecay();
+			if(object)
+			return object->GetID();
+			// fell through itemstruct
+	}
+	return 0; // fell through everything, this is bad/incomplete from perl
+}
+
 Mob* EntityList::GetTargetForMez(Mob* caster)
 {
 	if(!caster)
@@ -4332,6 +4384,21 @@
 	return n_list;
 }
 
+
+list<Object*> EntityList::GetObjectList()
+{
+	list<Object*> n_list;
+	LinkedListIterator<Object*> iterator(object_list); 
+	iterator.Reset();
+	while(iterator.MoreElements()) 
+	{
+		Object *ent = iterator.GetData();
+		n_list.push_back(ent);
+		iterator.Advance();
+	}
+	return n_list;
+}
+
 list<Client*> EntityList::GetClientList()
 {
 	list<Client*> c_list;
Index: entity.h
===================================================================
--- entity.h	(revision 1556)
+++ entity.h	(working copy)
@@ -131,6 +131,8 @@
 	Mob*	GetMob(const char* name);
 	Mob*	GetMobByNpcTypeID(int32 get_id);
 	NPC*	GetNPCByID(int16 id);
+	Object*	GetObjectByID(int16 id);
+	Object*	GetObjectByDBID(int32 id);
 	NPC*	GetNPCByNPCTypeID(int32 npc_id);
 	Client* GetClientByName(const char *name); 
 	Client* GetClientByAccID(int32 accid);
@@ -342,7 +344,8 @@
 	void    SaveAllClientsTaskState();
 	void    ReloadAllClientsTaskState(int TaskID=0);
 
-	void	CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time = 300000);
+	int16	CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time = 300000);
+	int16	CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, int8 type = 0x00);
 	void	ZoneWho(Client *c, Who_All_Struct* Who);
 	void	UnMarkNPC(int16 ID);
 
@@ -356,6 +359,7 @@
 
 	list<Mob*> GetMobList();
 	list<NPC*> GetNPCList();
+	list<Object*> GetObjectList();
 	list<Client*> GetClientList();
 	list<Corpse*> GetCorpseList();
 	void	DepopAll(int NPCTypeID, bool StartSpawnTimer = true);
Index: Object.cpp
===================================================================
--- Object.cpp	(revision 1556)
+++ Object.cpp	(working copy)
@@ -221,6 +221,40 @@
 	}
 }
 
+Object::Object(const char *model, float x, float y, float z, float heading, int8 type)
+ : respawn_timer(0), decay_timer(300000)
+{
+	user = NULL;
+	last_user = NULL;
+	
+	// Initialize members
+	m_id	= 0;
+	m_inst	= NULL;
+	m_type	= type;
+	m_icon	= 0;
+	m_inuse	= false;
+	m_ground_spawn = false;
+	// Set as much struct data as we can
+	memset(&m_data, 0, sizeof(Object_Struct));
+	m_data.heading = heading;
+	m_data.x = x;
+	m_data.y = y;
+	m_data.z = z;
+	m_data.zone_id = zone->GetZoneID();
+	//Hardcoded portion for unknown members
+	m_data.unknown024	= 0x7f001194;
+	m_data.unknown064	= 0;	//0x0000000D;
+	m_data.unknown068	= 0;	//0x0000001E;
+	m_data.unknown072	= 0;	//0x000032ED;
+	m_data.unknown076	= 0x0000d5fe;
+	m_data.unknown084	= 0xFFFFFFFF;
+
+	if(model)
+	strcpy(m_data.object_name, model);
+	else
+	strcpy(m_data.object_name, "IT64_ACTORDEF"); //default object name if model isn't specified for some unknown reason
+}
+
 Object::~Object()
 {
 	safe_delete(m_inst);
@@ -263,6 +297,19 @@
 	return true;
 }
 
+int16 Object::VarSave()
+{
+	if (m_id) {
+		// Update existing
+		database.UpdateObject(m_id, m_type, m_icon, m_data, m_inst);
+	}
+	else {
+		// Doesn't yet exist, add now
+		m_id = database.AddObject(m_type, m_icon, m_data, m_inst);
+	}	
+	return m_id;
+}
+
 // Remove object from database
 void Object::Delete(bool reset_state)
 {
@@ -648,6 +695,110 @@
 	return this->m_icon;
 }
 
+float Object::GetX()
+{	
+	return this->m_data.x;
+}
+
+float Object::GetY()
+{
+	return this->m_data.y;
+}
+
+
+float Object::GetZ()
+{
+	return this->m_data.z;
+}
+
+float Object::GetHeadingData()
+{
+	return this->m_data.heading;
+}
+
+void Object::SetX(float pos)
+{
+		this->m_data.x = pos;
+
+	EQApplicationPacket* app = new EQApplicationPacket();
+	EQApplicationPacket* app2 = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	this->CreateSpawnPacket(app2);
+	entity_list.QueueClients(0, app);
+	entity_list.QueueClients(0, app2);
+	safe_delete(app);
+	safe_delete(app2);
+}
+
+void Object::SetY(float pos)
+{
+		this->m_data.y = pos;
+
+	EQApplicationPacket* app = new EQApplicationPacket();
+	EQApplicationPacket* app2 = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	this->CreateSpawnPacket(app2);
+	entity_list.QueueClients(0, app);
+	entity_list.QueueClients(0, app2);
+	safe_delete(app);
+	safe_delete(app2);
+}
+
+void Object::Depop()
+{
+	EQApplicationPacket* app = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	entity_list.QueueClients(0, app);
+	safe_delete(app);
+	entity_list.RemoveObject(this->GetID());
+}
+
+void Object::Repop()
+{
+	EQApplicationPacket* app = new EQApplicationPacket();
+	EQApplicationPacket* app2 = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	this->CreateSpawnPacket(app2);
+	entity_list.QueueClients(0, app);
+	entity_list.QueueClients(0, app2);
+	safe_delete(app);
+	safe_delete(app2);
+}
+
+
+
+void Object::SetZ(float pos)
+{
+		this->m_data.z = pos;
+
+	EQApplicationPacket* app = new EQApplicationPacket();
+	EQApplicationPacket* app2 = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	this->CreateSpawnPacket(app2);
+	entity_list.QueueClients(0, app);
+	entity_list.QueueClients(0, app2);
+	safe_delete(app);
+	safe_delete(app2);
+}
+
+void Object::SetModelName(const char* modelname)
+{
+	strncpy(m_data.object_name, modelname, 20); // 20 is the max for chars in object_name, this should be safe
+	EQApplicationPacket* app = new EQApplicationPacket();
+	EQApplicationPacket* app2 = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	this->CreateSpawnPacket(app2);
+	entity_list.QueueClients(0, app);
+	entity_list.QueueClients(0, app2);
+	safe_delete(app);
+	safe_delete(app2);
+}
+
+const char* Object::GetModelName()
+{
+	return this->m_data.object_name;
+}
+
 void Object::SetIcon(int32 icon)
 {
 	this->m_icon = icon;
@@ -719,6 +870,14 @@
 	this->m_data.x = x;
 	this->m_data.y = y;
 	this->m_data.z = z;
+	EQApplicationPacket* app = new EQApplicationPacket();
+	EQApplicationPacket* app2 = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	this->CreateSpawnPacket(app2);
+	entity_list.QueueClients(0, app);
+	entity_list.QueueClients(0, app2);
+	safe_delete(app);
+	safe_delete(app2);
 }
 
 void Object::GetHeading(float* heading)
@@ -732,5 +891,13 @@
 void Object::SetHeading(float heading)
 {
 	this->m_data.heading = heading;
+	EQApplicationPacket* app = new EQApplicationPacket();
+	EQApplicationPacket* app2 = new EQApplicationPacket();
+	this->CreateDeSpawnPacket(app);
+	this->CreateSpawnPacket(app2);
+	entity_list.QueueClients(0, app);
+	entity_list.QueueClients(0, app2);
+	safe_delete(app);
+	safe_delete(app2);
 }
 
Index: object.h
===================================================================
--- object.h	(revision 1556)
+++ object.h	(working copy)
@@ -135,6 +135,7 @@
 	// Loading object from client dropping item on ground
 	Object(Client* client, const ItemInst* inst);
 	Object(const ItemInst *inst, float x, float y, float z, float heading, int32 decay_time);
+	Object(const char *model, float x, float y, float z, float heading, int8 type);
 	
 	// Destructor
 	~Object();
@@ -153,6 +154,8 @@
 	// Packet functions
 	void CreateSpawnPacket(EQApplicationPacket* app);
 	void CreateDeSpawnPacket(EQApplicationPacket* app);
+	void Depop();
+	void Repop();
 	
 	//Decay functions
 	void StartDecay() {decay_timer.Start();}
@@ -165,6 +168,7 @@
 	// Override base class implementations
 	virtual bool IsObject()	const { return true; }
 	virtual bool Save();
+	virtual int16 VarSave();
 	virtual void SetID(int16 set_id);
 	
 	void ClearUser() { user = NULL; }
@@ -172,6 +176,7 @@
 	int32 GetDBID();
 	int32 GetType();
 	void  SetType(int32 type);
+	void  SetDBID(int32 dbid);
 	int32 GetIcon();
 	void  SetIcon(int32 icon);
 	int32 GetItemID();
@@ -181,6 +186,15 @@
 	void GetLocation(float* x, float* y, float* z);
 	void SetLocation(float x, float y, float z);
 	void GetHeading(float* heading);
+	float GetX();
+	float GetY();
+	float GetZ();
+	float GetHeadingData();
+	void SetX(float pos);
+	void SetY(float pos);
+	void SetZ(float pos);
+	void SetModelName(const char* modelname);
+	const char* GetModelName();
 	void SetHeading(float heading);
 
 protected:
Index: perl_entity.cpp
===================================================================
--- perl_entity.cpp	(revision 1556)
+++ perl_entity.cpp	(working copy)
@@ -173,6 +173,61 @@
 	XSRETURN(1);
 }
 
+XS(XS_EntityList_GetObjectByDBID); /* prototype to pass -Wmissing-prototypes */
+XS(XS_EntityList_GetObjectByDBID)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: EntityList::GetObjectByDBID(THIS, id)");
+	{
+		EntityList *		THIS;
+		Object *		RETVAL;
+		int32		id = (int32)SvUV(ST(1));
+
+		if (sv_derived_from(ST(0), "EntityList")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(EntityList *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type EntityList");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetObjectByDBID(id);
+		ST(0) = sv_newmortal();
+		sv_setref_pv(ST(0), "Object", (void*)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+XS(XS_EntityList_GetObjectByID); /* prototype to pass -Wmissing-prototypes */
+XS(XS_EntityList_GetObjectByID)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: EntityList::GetObjectByID(THIS, id)");
+	{
+		EntityList *		THIS;
+		Object *		RETVAL;
+		int32		id = (int32)SvUV(ST(1));
+
+		if (sv_derived_from(ST(0), "EntityList")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(EntityList *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type EntityList");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetObjectByID(id);
+		ST(0) = sv_newmortal();
+		sv_setref_pv(ST(0), "Object", (void*)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+
 XS(XS_EntityList_GetNPCByNPCTypeID); /* prototype to pass -Wmissing-prototypes */
 XS(XS_EntityList_GetNPCByNPCTypeID)
 {
@@ -1797,6 +1852,42 @@
 	XSRETURN(num_npcs);
 }
 
+XS(XS_EntityList_GetObjectList); /* prototype to pass -Wmissing-prototypes */
+XS(XS_EntityList_GetObjectList)
+{
+	dXSARGS;
+	int num_objects = 0;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: EntityList::GetObjectList(THIS)");
+	{
+		EntityList *THIS;
+
+		if (sv_derived_from(ST(0), "EntityList")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(EntityList *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type EntityList");
+
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		std::list<Object*> object_list = entity_list.GetObjectList();
+		std::list<Object*>::iterator iter = object_list.begin();
+
+		while(iter != object_list.end())
+		{
+			Object *entry = (*iter);
+			ST(0) = sv_newmortal();
+			sv_setref_pv(ST(0), "Object", (void*)entry);
+			XPUSHs(ST(0));
+			num_objects++;
+			iter++;
+		}
+	}
+	XSRETURN(num_objects);
+}
+
 XS(XS_EntityList_GetCorpseList); /* prototype to pass -Wmissing-prototypes */
 XS(XS_EntityList_GetCorpseList)
 {
@@ -1884,6 +1975,8 @@
 		newXSproto(strcpy(buf, "GetMobByID"), XS_EntityList_GetMobByID, file, "$$");
 		newXSproto(strcpy(buf, "GetMobByNpcTypeID"), XS_EntityList_GetMobByNpcTypeID, file, "$$");
 		newXSproto(strcpy(buf, "GetNPCByID"), XS_EntityList_GetNPCByID, file, "$$");
+		newXSproto(strcpy(buf, "GetObjectByID"), XS_EntityList_GetObjectByID, file, "$");
+		newXSproto(strcpy(buf, "GetObjectByDBID"), XS_EntityList_GetObjectByDBID, file, "$");
 		newXSproto(strcpy(buf, "GetNPCByNPCTypeID"), XS_EntityList_GetNPCByNPCTypeID, file, "$$");
 		newXSproto(strcpy(buf, "GetClientByName"), XS_EntityList_GetClientByName, file, "$$");
 		newXSproto(strcpy(buf, "GetClientByAccID"), XS_EntityList_GetClientByAccID, file, "$$");
@@ -1940,6 +2033,7 @@
 		newXSproto(strcpy(buf, "GetMobList"), XS_EntityList_GetMobList, file, "$");
 		newXSproto(strcpy(buf, "GetClientList"), XS_EntityList_GetClientList, file, "$");
 		newXSproto(strcpy(buf, "GetNPCList"), XS_EntityList_GetNPCList, file, "$");
+		newXSproto(strcpy(buf, "GetObjectList"), XS_EntityList_GetObjectList, file, "$");
 		newXSproto(strcpy(buf, "GetCorpseList"), XS_EntityList_GetCorpseList, file, "$");
 		newXSproto(strcpy(buf, "SignalAllClients"), XS_EntityList_SignalAllClients, file, "$$");
 	XSRETURN_YES;
Index: perl_object.cpp
===================================================================
--- perl_object.cpp	(revision 0)
+++ perl_object.cpp	(revision 0)
@@ -0,0 +1,883 @@
+/*
+ * This file was generated automatically by xsubpp version 1.9508 from the
+ * contents of tmp. Do not edit this file, edit tmp instead.
+ *
+ *		ANY CHANGES MADE HERE WILL BE LOST!
+ *
+ */
+
+
+/*  EQEMu:  Everquest Server Emulator
+	Copyright (C) 2001-2004  EQEMu Development Team (http://eqemulator.net)
+
+	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; version 2 of the License.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY except by those people which sell it, which
+		are required to give you total support for your newly bought product;
+		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, write to the Free Software
+	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "features.h"
+#ifdef EMBPERL_XS_CLASSES
+#include "../common/debug.h"
+#include "embperl.h"
+
+#include "object.h"
+
+#ifdef THIS	 /* this macro seems to leak out on some systems */
+#undef THIS		
+#endif
+
+XS(XS_Object_IsGroundSpawn); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_IsGroundSpawn)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::IsGroundSpawn(THIS)");
+	{
+		Object *		THIS;
+		bool		RETVAL;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->IsGroundSpawn();
+		ST(0) = boolSV(RETVAL);
+		sv_2mortal(ST(0));
+	}
+	XSRETURN(1);
+}
+
+
+
+XS(XS_Object_Close); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_Close)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::Close(THIS)");
+	{
+		Object *		THIS;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->Close();
+	}
+	XSRETURN_EMPTY;
+}
+
+
+XS(XS_Object_Delete); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_Delete)
+{
+	dXSARGS;
+	if (items < 1 || items > 2)
+		Perl_croak(aTHX_ "Usage: Object::Delete(THIS, reset_state=false)");
+	{
+		Object *		THIS;
+		bool		reset_state;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		if (items < 2)
+			reset_state = false;
+		else {
+			reset_state = (bool)SvTRUE(ST(1));
+		}
+
+		THIS->Delete(reset_state);
+	}
+	XSRETURN_EMPTY;
+}
+XS(XS_Object_StartDecay); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_StartDecay)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::StartDecay(THIS)");
+	{
+		Object *		THIS;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->StartDecay();
+	}
+	XSRETURN_EMPTY;
+}
+
+
+XS(XS_Object_DeleteItem); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_DeleteItem)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::DeleteItem(THIS, index)");
+	{
+		Object *		THIS;
+		uint8		index = (uint8)SvUV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->DeleteItem(index);
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_IsObject); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_IsObject)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::IsObject(THIS)");
+	{
+		Object *		THIS;
+		bool		RETVAL;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->IsObject();
+		ST(0) = boolSV(RETVAL);
+		sv_2mortal(ST(0));
+	}
+	XSRETURN(1);
+}
+
+
+XS(XS_Object_Save); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_Save)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::Save(THIS)");
+	{
+		Object *		THIS;
+		bool		RETVAL;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->Save();
+		ST(0) = boolSV(RETVAL);
+		sv_2mortal(ST(0));
+	}
+	XSRETURN(1);
+}
+
+
+XS(XS_Object_SetID); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetID)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetID(THIS, set_id)");
+	{
+		Object *		THIS;
+		int16		set_id = (int16)SvUV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetID(set_id);
+	}
+	XSRETURN_EMPTY;
+}
+
+
+XS(XS_Object_ClearUser); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_ClearUser)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::ClearUser(THIS)");
+	{
+		Object *		THIS;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->ClearUser();
+	}
+	XSRETURN_EMPTY;
+}
+
+
+XS(XS_Object_GetDBID); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetDBID)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetDBID(THIS)");
+	{
+		Object *		THIS;
+		int32		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetDBID();
+		XSprePUSH; PUSHu((UV)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+XS(XS_Object_GetID); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetID)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetID(THIS)");
+	{
+		Object *		THIS;
+		int16		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetID();
+		XSprePUSH; PUSHu((UV)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+XS(XS_Object_GetX); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetX)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetX(THIS)");
+	{
+		Object *		THIS;
+		float		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetX();
+		XSprePUSH; PUSHn((double)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+XS(XS_Object_GetY); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetY)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetY(THIS)");
+	{
+		Object *		THIS;
+		float		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetY();
+		XSprePUSH; PUSHn((double)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+XS(XS_Object_GetZ); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetZ)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetZ(THIS)");
+	{
+		Object *		THIS;
+		float		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetZ();
+		XSprePUSH; PUSHn((double)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+XS(XS_Object_GetHeading); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetHeading)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetHeadingData(THIS)");
+	{
+		Object *		THIS;
+		float		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetHeadingData();
+		XSprePUSH; PUSHn((double)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+XS(XS_Object_VarSave); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_VarSave)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::VarSave(THIS)");
+	{
+		Object *		THIS;
+		int32		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->VarSave();
+		XSprePUSH; PUSHu((UV)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+
+XS(XS_Object_GetType); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetType)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetType(THIS)");
+	{
+		Object *		THIS;
+		int32		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetType();
+		XSprePUSH; PUSHu((UV)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+
+XS(XS_Object_SetType); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetType)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetType(THIS, type)");
+	{
+		Object *		THIS;
+		int32		type = (int32)SvUV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetType(type);
+	}
+	XSRETURN_EMPTY;
+}
+
+
+XS(XS_Object_GetIcon); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetIcon)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetIcon(THIS)");
+	{
+		Object *		THIS;
+		int32		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetIcon();
+		XSprePUSH; PUSHu((UV)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+
+XS(XS_Object_SetIcon); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetIcon)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetIcon(THIS, icon)");
+	{
+		Object *		THIS;
+		int32		icon = (int32)SvUV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetIcon(icon);
+	}
+	XSRETURN_EMPTY;
+}
+
+
+XS(XS_Object_GetItemID); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetItemID)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetItemID(THIS)");
+	{
+		Object *		THIS;
+		int32		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetItemID();
+		XSprePUSH; PUSHu((UV)RETVAL);
+	}
+	XSRETURN(1);
+}
+
+
+XS(XS_Object_SetItemID); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetItemID)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetItemID(THIS, itemid)");
+	{
+		Object *		THIS;
+		int32		itemid = (int32)SvUV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetItemID(itemid);
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_SetLocation); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetLocation)
+{
+	dXSARGS;
+	if (items != 4)
+		Perl_croak(aTHX_ "Usage: Object::SetLocation(THIS, x, y, z)");
+	{
+		Object *		THIS;
+		float		x = (float)SvNV(ST(1));
+		float		y = (float)SvNV(ST(2));
+		float		z = (float)SvNV(ST(3));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetLocation(x, y, z);
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_SetX); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetX)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetX(THIS, XPos)");
+	{
+		Object *		THIS;
+		float		pos = (float)SvNV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetX(pos);
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_SetY); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetY)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetY(THIS, YPos)");
+	{
+		Object *		THIS;
+		float		pos = (float)SvNV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetY(pos);
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_SetZ); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetZ)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetZ(THIS, ZPos)");
+	{
+		Object *		THIS;
+		float		pos = (float)SvNV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetZ(pos);
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_SetHeading); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetHeading)
+{
+	dXSARGS;
+	if (items != 2)
+		Perl_croak(aTHX_ "Usage: Object::SetHeading(THIS, heading)");
+	{
+		Object *		THIS;
+		float		heading = (float)SvNV(ST(1));
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		THIS->SetHeading(heading);
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_SetModelName); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_SetModelName)
+{
+	dXSARGS;
+	if (items < 1 || items > 2)
+		Perl_croak(aTHX_ "Usage: Object::SetModelName(THIS, name)");
+	{
+		Object *		THIS;
+		char *		name = NULL;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		if (items > 1)	{	name = (char *)SvPV_nolen(ST(1));	}
+
+		THIS->SetModelName(name);
+	}
+	XSRETURN_EMPTY;
+}
+XS(XS_Object_GetModelName); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_GetModelName)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::GetModelName(THIS)");
+	{
+		Object *		THIS;
+		Const_char *		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+
+		RETVAL = THIS->GetModelName();
+		sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
+	}
+	XSRETURN(1);
+}
+
+XS(XS_Object_Repop); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_Repop)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::Repop(THIS)");
+	{
+		Object *		THIS;
+		Const_char *		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+		THIS->Repop();
+	}
+	XSRETURN_EMPTY;
+}
+
+XS(XS_Object_Depop); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Object_Depop)
+{
+	dXSARGS;
+	if (items != 1)
+		Perl_croak(aTHX_ "Usage: Object::Repop(THIS)");
+	{
+		Object *		THIS;
+		Const_char *		RETVAL;
+		dXSTARG;
+
+		if (sv_derived_from(ST(0), "Object")) {
+			IV tmp = SvIV((SV*)SvRV(ST(0)));
+			THIS = INT2PTR(Object *,tmp);
+		}
+		else
+			Perl_croak(aTHX_ "THIS is not of type Object");
+		if(THIS == NULL)
+			Perl_croak(aTHX_ "THIS is NULL, avoiding crash.");
+		THIS->Depop();
+	}
+	XSRETURN_EMPTY;
+}
+
+#ifdef __cplusplus
+extern "C"
+#endif
+XS(boot_Object); /* prototype to pass -Wmissing-prototypes */
+XS(boot_Object)
+{
+	dXSARGS;
+	char file[256];
+	strncpy(file, __FILE__, 256);
+	file[255] = 0;
+	
+	if(items != 1)
+		fprintf(stderr, "boot_quest does not take any arguments.");
+	char buf[128];
+
+	//add the strcpy stuff to get rid of const warnings....
+
+
+
+	XS_VERSION_BOOTCHECK ;
+		newXSproto(strcpy(buf, "Depop"),XS_Object_Depop, file, "$");
+		newXSproto(strcpy(buf, "Repop"),XS_Object_Repop, file, "$");
+		newXSproto(strcpy(buf, "SetModelName"),XS_Object_SetModelName, file, "$$");
+		newXSproto(strcpy(buf, "GetModelName"),XS_Object_GetModelName, file, "$");
+		newXSproto(strcpy(buf, "GetX"),XS_Object_GetX, file, "$");
+		newXSproto(strcpy(buf, "GetY"),XS_Object_GetY, file, "$");
+		newXSproto(strcpy(buf, "GetZ"),XS_Object_GetZ, file, "$");
+		newXSproto(strcpy(buf, "GetHeading"),XS_Object_GetHeading, file, "$");
+		newXSproto(strcpy(buf, "SetX"),XS_Object_SetX, file, "$$");
+		newXSproto(strcpy(buf, "SetY"),XS_Object_SetY, file, "$$");
+		newXSproto(strcpy(buf, "SetZ"),XS_Object_SetZ, file, "$$");
+		newXSproto(strcpy(buf, "SetHeading"),XS_Object_SetHeading, file, "$$");
+		newXSproto(strcpy(buf, "SetLocation"),XS_Object_SetLocation, file, "$$$$");
+		newXSproto(strcpy(buf, "SetItemID"),XS_Object_SetItemID, file, "$$");
+		newXSproto(strcpy(buf, "GetItemID"),XS_Object_GetItemID, file, "$");
+		newXSproto(strcpy(buf, "SetIcon"),XS_Object_SetIcon, file, "$$");
+		newXSproto(strcpy(buf, "GetIcon"),XS_Object_GetIcon, file, "$");
+		newXSproto(strcpy(buf, "SetType"),XS_Object_SetType, file, "$$");
+		newXSproto(strcpy(buf, "GetType"),XS_Object_GetType, file, "$");
+		newXSproto(strcpy(buf, "GetDBID"),XS_Object_GetDBID, file, "$");
+		newXSproto(strcpy(buf, "ClearUser"),XS_Object_ClearUser, file, "$");
+		newXSproto(strcpy(buf, "SetID"),XS_Object_SetID, file, "$$");
+		newXSproto(strcpy(buf, "GetID"),XS_Object_GetID, file, "$");
+		newXSproto(strcpy(buf, "Save"),XS_Object_Save, file, "$");
+		newXSproto(strcpy(buf, "VarSave"),XS_Object_VarSave, file, "$");
+		newXSproto(strcpy(buf, "DeleteItem"),XS_Object_DeleteItem, file, "$$");
+		newXSproto(strcpy(buf, "StartDecay"),XS_Object_StartDecay, file, "$$");
+		newXSproto(strcpy(buf, "Delete"),XS_Object_Delete, file, "$$");
+		newXSproto(strcpy(buf, "IsGroundSpawn"),XS_Object_IsGroundSpawn, file, "$");
+		newXSproto(strcpy(buf, "Close"),XS_Object_Close, file, "$");
+	XSRETURN_YES;
+}
+#endif //EMBPERL_XS_CLASSES
+
Index: perlparser.cpp
===================================================================
--- perlparser.cpp	(revision 1556)
+++ perlparser.cpp	(working copy)
@@ -90,6 +90,9 @@
 	"package HateEntry;"
 	"&boot_HateEntry;"	// load quest item XS
 
+	"package Object;"
+	"&boot_Object;"	// load quest item XS
+
 #endif
 	"package main;"
 	"}"
@@ -2540,17 +2543,44 @@
 	float y = (float)SvNV(ST(2));
 	float z = (float)SvNV(ST(3));
 	float heading = (float)SvNV(ST(4));
+	uint16 id = 0;
 
 	if(items == 5)
-		quest_manager.CreateGroundObject(itemid, x, y, z, heading);
+		id = quest_manager.CreateGroundObject(itemid, x, y, z, heading);
 	else{
 		int32 decay_time = (int32)SvIV(ST(5));
-		quest_manager.CreateGroundObject(itemid, x, y, z, heading, decay_time);
+		id = quest_manager.CreateGroundObject(itemid, x, y, z, heading, decay_time);
 	}
 
-	XSRETURN_EMPTY;
+
+	XSRETURN_IV(id);
 }
 
+XS(XS__CreateGroundObjectFromModel);
+XS(XS__CreateGroundObjectFromModel)
+{
+	dXSARGS;
+	if (items != 5 && items != 6)
+		Perl_croak(aTHX_ "Usage: CreateGroundObjectFromModel(modelname, x, y, z, heading, [type])");
+
+	char *		modelname = (char *)SvPV_nolen(ST(0));
+	float x = (float)SvNV(ST(1));
+	float y = (float)SvNV(ST(2));
+	float z = (float)SvNV(ST(3));
+	float heading = (float)SvNV(ST(4));
+	uint16 id = 0;
+
+	if(items == 5)
+		id = quest_manager.CreateGroundObjectFromModel(modelname, x, y, z, heading);
+	else{
+		int32 type = (int32)SvIV(ST(5));
+		id = quest_manager.CreateGroundObjectFromModel(modelname, x, y, z, heading, type);
+	}
+
+
+	XSRETURN_IV(id);
+}
+
 XS(XS__ModifyNPCStat);
 XS(XS__ModifyNPCStat)
 {
@@ -3157,6 +3187,7 @@
 		newXS(strcpy(buf, "we"), XS__we, file);
 		newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
 		newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file);
+		newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file);
 		newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file);
         newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
 		newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
Index: questmgr.cpp
===================================================================
--- questmgr.cpp	(revision 1556)
+++ questmgr.cpp	(working copy)
@@ -1933,11 +1933,20 @@
 		return 0;
 }
 
-void QuestManager::CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time)
+int16 QuestManager::CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time)
 {
-	entity_list.CreateGroundObject(itemid, x, y, z, heading, decay_time);
+	int16 entid = 0; //safety check
+	entid = entity_list.CreateGroundObject(itemid, x, y, z, heading, decay_time);
+	return entid;
 }
 
+int16 QuestManager::CreateGroundObjectFromModel(const char *model, float x, float y, float z, float heading, int8 type)
+{
+	int16 entid = 0; //safety check
+	entid = entity_list.CreateGroundObjectFromModel(model, x, y, z, heading, type);
+	return entid;
+}
+
 void QuestManager::ModifyNPCStat(const char *identifier, const char *newValue)
 {
 	if(owner){
Index: questmgr.h
===================================================================
--- questmgr.h	(revision 1556)
+++ questmgr.h	(working copy)
@@ -191,7 +191,8 @@
    	bool checktitle(int titlecheck);
    	void removetitle(int titlecheck);
 
-	void CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time = 300000);
+	int16 CreateGroundObject(int32 itemid, float x, float y, float z, float heading, int32 decay_time = 300000);
+	int16 CreateGroundObjectFromModel(const char* model, float x, float y, float z, float heading, int8 type = 0x00);
 	void ModifyNPCStat(const char *identifier, const char *newValue);
 	void UpdateSpawnTimer(int32 id, int32 newTime);
 
Index: Zone.vcproj
===================================================================
--- Zone.vcproj	(revision 1556)
+++ Zone.vcproj	(working copy)
@@ -572,6 +572,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\perl_object.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\perl_perlpacket.cpp"
 				>
 			</File>

Last edited by Secrets; 06-22-2010 at 01:04 PM..
Reply With Quote
  #2  
Old 06-15-2010, 01:02 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

I added a feature to this to be able to get objects by DB id, and objects by entity list ID.

I also added the option of getting the object's entity id.

In addition to the other ways of getting an object, there is now a returned value on CreateGroundObject perl command for entity ID.

This *should* allow people to make permanent fixtures via perl, if they use $object->Save() on a temporarily spawned object. That will give it a DB ID if it has none. Now to have some sort of save return a DB and set it...

Will post a diff soon.
Reply With Quote
  #3  
Old 06-15-2010, 01:19 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Added more to my previous post. I added the command VarSave, which saves it to the database and returns the DBID that it saves. It also sets the DB on the object immediately.

Testing it now, but updated the first post with the diff.
Reply With Quote
  #4  
Old 06-15-2010, 01:43 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Fixed some dumb errors I made. Diff updated.
Reply With Quote
  #5  
Old 06-16-2010, 06:21 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Updated the post with moving objects' location & heading, updated in realtime.
Reply With Quote
  #6  
Old 06-16-2010, 08:27 AM
steve
Discordant
 
Join Date: Jan 2002
Posts: 305
Default

I guess I don't understand what exactly this is/does.
Reply With Quote
  #7  
Old 06-16-2010, 09:39 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Quote:
Originally Posted by steve View Post
I guess I don't understand what exactly this is/does.
Allows the objects (tradeskill containers, which can be substituted with door models) in the world to be controlled via perl. There's an objects class which controls all of that. Since doors cannot be despawned and respawned easily in code without a complete rework, (they are loaded from the database exclusively), I chose this instead. For example, if you wanted to move a forge around with db ID 24 to an NPC, you would do something similar to this:

Code:
sub EVENT_SAY {
if($text=~/hail/i)
{
my $ent = entity_list.GetObjectByDBID(24);
if($ent)
{
$ent->SetLocation($npc->GetX(), $npc->GetY(), $npc->GetZ());
$ent->SetHeading($npc->GetHeading());
quest::say("Object moved to my location!");
}
}
}
Reply With Quote
  #8  
Old 06-20-2010, 12:48 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Updated first post again, added object functions SetX, SetY, SetZ, SetHeading, GetX, GetY, GetZ, GetHeading, SetModelName, GetModelName, and added a new quest command (int16 CreateGroundObjectFromModel, quest::creategroundobjectfrommodel(string modelname, x, y, z, heading, int8 [type]))

All of the set commands update in realtime via a despawn/respawn packet.
Reply With Quote
  #9  
Old 06-20-2010, 01:54 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Upon further inspection... what i was trying to do with objects could be accomplished by adding functions to doors. ._.

So i'll probably keep this here for reference and start a new topic with door perl.
Reply With Quote
  #10  
Old 06-20-2010, 02:17 PM
Zordana
Sarnak
 
Join Date: Jan 2010
Posts: 38
Default

This is pretty awesome what youve done there..

Here is my contribution (object builder npc)
http://www.eqemulator.org/forums/sho...d.php?p=189005
Reply With Quote
  #11  
Old 06-21-2010, 08:54 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Seems like there isn't a door despawn packet so this is still relevant. Shame, i'd like dynamic spawnable models, but I guess that isn't the case :(
Reply With Quote
  #12  
Old 06-22-2010, 01:04 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,447
Default

Updated first post again to add $object->Repop() and $object->Depop()
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 11:28 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3