Last active
December 31, 2017 17:03
-
-
Save Southclaws/99ec19c15c31d99fd215 to your computer and use it in GitHub Desktop.
Southclaw's "Object Oriented" modular style for Pawn. This documents the basics of structuring a create/destroy type entity. This method can be used for almost any kind of "thing" that can be created, destroyed and modified within its life cycle. Sure it's not *real* object oriented programming but it uses the same methodologies and lifecycle co…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Southclaw's "Object Oriented" modular coding style for Pawn. This documents | |
the basics of structuring a create/destroy type entity. This method can be | |
used for almost any kind of "thing" that can be created, destroyed and | |
modified within its life cycle. | |
*/ | |
#include <YSI\y_hooks> | |
/* | |
We're using the generic term "entity" in this example. This could be | |
anything, a SIF/Button, an object, a vehicle, a pickup, a combination of all | |
of those! | |
*/ | |
#define MAX_ENTITY (64) | |
/* | |
Enumerator contains the structure for each entity's "instance". Think of | |
this as a class or struct in OO languages. Nothing to do with functions or | |
"methods" though, just a storage structure for data associated with each | |
entity. | |
*/ | |
enum E_ENTITY_DATA { | |
Float:ent_posX, | |
Float:ent_posY, | |
Float:ent_posZ | |
} | |
/* | |
Static globals are used here since this "module" is designed to be included | |
into a gamemode or filterscript and we don't want names to conflict. Global | |
variables declared as static will only be accessible inside the file. | |
*/ | |
static | |
// Contains the data for each entity | |
ent_Data[MAX_ENTITY][E_ENTITY_DATA], | |
// Contains the index of all entities. | |
Iterator:ent_Index<MAX_ENTITY>; | |
/* | |
The "constructor" function, you'll be familiar with this concept if you've | |
ever seen an OO language. This function creates entities and returns their | |
"handle" or "id" number (a value from 0 to MAX_ENTITY (64)). | |
*/ | |
stock CreateEntity(Float:x, Float:y, Float:z) { | |
// Get the first free ID using the y_iterate index. | |
new id = Iter_Free(ent_Index); | |
// Invalid iterator index? Index is full or something else went wrong. | |
if(id == ITER_NONE) { | |
return -1; // return an invalid index | |
} | |
// ID is valid, fill in our entity's data fields. | |
ent_Data[id][ent_posX] = x; | |
ent_Data[id][ent_posY] = y; | |
ent_Data[id][ent_posZ] = z; | |
// Return the ID back to where the function was called, this is important | |
// so the entity can be addressed in some way. This ID can be used to | |
// modify the entity or destroy it. If this ID is lost, the entity can't be | |
// explicitly interacted with or destroyed (possible orphan!). | |
return id; | |
} | |
/* | |
Our destroy function takes an ID (the same kind of value returned from the | |
constructor) and frees up the memory again while also making the ID | |
available for use. It also clears | |
*/ | |
stock DestroyEntity(entityid) { | |
// If the entity ID isn't in the index, don't bother running the function. | |
if(!Iter_Contains(ent_Index, entityid)) { | |
return 1; // return non-zero, zero means success | |
} | |
// Resetting the values isn't always necessary, it's just a habit I have. | |
ent_Data[entityid][ent_posX] = 0.0; | |
ent_Data[entityid][ent_posY] = 0.0; | |
ent_Data[entityid][ent_posZ] = 0.0; | |
// Free up the slot in the index ready for another entity to take its place. | |
Iter_Remove(ent_Index, entityid); | |
return 0; // zero means success | |
} | |
/* | |
Manipulation functions go at the bottom of the file, these are functions | |
that are designed to get/set the values held within the enum structure. | |
*/ | |
stock GetEntityPos(entityid, &Float:x, &Float:y, &Float:z) { | |
// Non-existent entity? Don't bother with the function. | |
if(!Iter_Contains(ent_Index, entityid)) { | |
return 1; // non-zero means failure | |
} | |
x = ent_Data[entityid][ent_posX]; | |
y = ent_Data[entityid][ent_posY]; | |
z = ent_Data[entityid][ent_posZ]; | |
return 0; // zero means success | |
} | |
stock SetEntityPos(entityid, Float:x, Float:y, Float:z) { | |
// Non-existent entity? Don't bother with the function. | |
if(!Iter_Contains(ent_Index, entityid)) { | |
return 1; // non-zero means failure | |
} | |
ent_Data[entityid][ent_posX] = x; | |
ent_Data[entityid][ent_posY] = y; | |
ent_Data[entityid][ent_posZ] = z; | |
return 0; // zero means success | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment