Initial item system setup
authorTimePath <andrew.hardaker1995@gmail.com>
Sun, 10 May 2015 09:19:51 +0000 (19:19 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sun, 10 May 2015 09:19:51 +0000 (19:19 +1000)
17 files changed:
qcsrc/client/main.qc
qcsrc/client/progs.src
qcsrc/common/items/all.inc [new file with mode: 0644]
qcsrc/common/items/all.qc [new file with mode: 0644]
qcsrc/common/items/all.qh [new file with mode: 0644]
qcsrc/common/items/item.qc [new file with mode: 0644]
qcsrc/common/items/item.qh [new file with mode: 0644]
qcsrc/common/items/item/ammo.qc [new file with mode: 0644]
qcsrc/common/items/item/ammo.qh [new file with mode: 0644]
qcsrc/common/items/item/buff.qc [new file with mode: 0644]
qcsrc/common/items/item/buff.qh [new file with mode: 0644]
qcsrc/common/oo.qh [new file with mode: 0644]
qcsrc/menu/menu.qc
qcsrc/menu/oo/base.qh
qcsrc/menu/progs.src
qcsrc/server/g_world.qc
qcsrc/server/progs.src

index 5343c18..ad727bf 100644 (file)
@@ -39,6 +39,8 @@
 #include "../common/stats.qh"
 #include "../common/teams.qh"
 
+#include "../common/items/all.qh"
+
 #include "../common/weapons/weapons.qh"
 
 #include "../csqcmodellib/cl_model.qh"
@@ -136,6 +138,7 @@ void CSQC_Init(void)
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
        CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
+       CALL_ACCUMULATED_FUNCTION(RegisterItems);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
index 36d159c..5fbff74 100644 (file)
@@ -55,6 +55,8 @@ weapons/projectile.qc // TODO
 ../common/urllib.qc
 ../common/util.qc
 
+../common/items/all.qc
+
 ../common/monsters/monsters.qc
 
 ../common/weapons/weapons.qc // TODO
diff --git a/qcsrc/common/items/all.inc b/qcsrc/common/items/all.inc
new file mode 100644 (file)
index 0000000..24f7955
--- /dev/null
@@ -0,0 +1,4 @@
+#include "item.qc"
+
+#include "item/ammo.qc"
+#include "item/buff.qc"
diff --git a/qcsrc/common/items/all.qc b/qcsrc/common/items/all.qc
new file mode 100644 (file)
index 0000000..1700ae9
--- /dev/null
@@ -0,0 +1,11 @@
+#include "all.qh"
+
+#include "all.inc"
+
+void ItemTest()
+{
+    ITEMS_FOREACH(it != NULL, LAMBDA({
+        print(strcat(etos(it), "\n"));
+        ITEM_SEND(Default, it);
+    }));
+}
diff --git a/qcsrc/common/items/all.qh b/qcsrc/common/items/all.qh
new file mode 100644 (file)
index 0000000..74ca110
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef ALL_H
+#define ALL_H
+
+const int MAX_ITEMS = 23;
+entity ITEMS[MAX_ITEMS];
+
+#define ITEMS_FOREACH(pred, body) do {      \
+    for (int i = 0; i < ITEM_COUNT; i++) {  \
+        const entity it = ITEMS[i];         \
+        if (pred) { body }                  \
+    }                                       \
+} while(0)
+
+void RegisterItems();
+void ItemTest();
+
+#ifdef CSQC
+void ReadItems()
+{
+/*
+    const int flags = read();
+    for (int i = 0; i < MAX_ITEMS; i++) {
+        if (flags & BIT(i)) {
+            self.items[i] = read();
+        }
+    }
+*/
+}
+#endif
+
+#ifdef SVQC
+void WriteItems()
+{
+
+}
+#endif
+
+#endif
diff --git a/qcsrc/common/items/item.qc b/qcsrc/common/items/item.qc
new file mode 100644 (file)
index 0000000..a8cf566
--- /dev/null
@@ -0,0 +1,11 @@
+#include "item.qh"
+
+bool GameItem_respondTo(entity this, int request)
+{
+    switch (request) {
+        default: return false;
+        case ITEM_SIGNAL(Default):
+            print("Item responding\n");
+            return true;
+    }
+}
diff --git a/qcsrc/common/items/item.qh b/qcsrc/common/items/item.qh
new file mode 100644 (file)
index 0000000..cf2779a
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef GAMEITEM_H
+#define GAMEITEM_H
+#include "../oo.qh"
+CLASS(GameItem, Object)
+    METHOD(GameItem, respondTo, bool(entity, int))
+ENDCLASS(GameItem)
+
+
+
+#define LAMBDA(...) { __VA_ARGS__ ; }
+
+#define ITEM_SIGNALS(_) \
+    _(Default, void, (entity it), LAMBDA({ it.respondTo(it, SIGNAL); })) \
+    /* Common item signals */
+
+#define ITEM_SIGNAL(id) __Item_Signal_##id
+
+#define ITEM_ENUM(id, ret, params, body) ITEM_SIGNAL(id) ,
+enum { ITEM_SIGNALS(ITEM_ENUM) };
+#undef ITEM_ENUM
+
+#define ITEM_SEND(id, ret, params, body) ret __Item_Send_##id params { const noref int SIGNAL = ITEM_SIGNAL(id); body }
+ITEM_SIGNALS(ITEM_SEND)
+#undef ITEM_SEND
+#define ITEM_SEND(id, ...) __Item_Send_##id(__VA_ARGS__)
+
+
+
+int ITEM_COUNT;
+#define REGISTER_ITEM(id, class, body)          \
+    void RegisterItems_##id() {                 \
+        const noref entity this = NEW(class);   \
+        ITEMS[ITEM_COUNT++] = this;             \
+        body                                    \
+    }                                           \
+    ACCUMULATE_FUNCTION(RegisterItems, RegisterItems_##id)
+
+#endif
diff --git a/qcsrc/common/items/item/ammo.qc b/qcsrc/common/items/item/ammo.qc
new file mode 100644 (file)
index 0000000..5868eeb
--- /dev/null
@@ -0,0 +1,18 @@
+#include "ammo.qh"
+
+#define REGISTER_AMMO(id) REGISTER_ITEM(id, Ammo, LAMBDA(this.ammoName = #id))
+REGISTER_AMMO(nails)
+REGISTER_AMMO(rockets)
+REGISTER_AMMO(cells)
+REGISTER_AMMO(plasma)
+REGISTER_AMMO(fuel)
+
+bool Ammo_respondTo(entity this, int request)
+{
+    switch (request) {
+        default: return false;
+        case ITEM_SIGNAL(Default):
+            print(strcat(this.ammoName, " responding\n"));
+            return true;
+    }
+}
diff --git a/qcsrc/common/items/item/ammo.qh b/qcsrc/common/items/item/ammo.qh
new file mode 100644 (file)
index 0000000..412ccc2
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef AMMO_H
+#define AMMO_H
+#include "../item.qh"
+CLASS(Ammo, GameItem)
+    METHOD(Ammo, respondTo, bool(entity, int))
+    ATTRIB(Ammo, ammoName, string, string_null)
+ENDCLASS(Ammo)
+#endif
diff --git a/qcsrc/common/items/item/buff.qc b/qcsrc/common/items/item/buff.qc
new file mode 100644 (file)
index 0000000..479df88
--- /dev/null
@@ -0,0 +1,13 @@
+#include "buff.qh"
+
+REGISTER_ITEM(strength, Buff, LAMBDA())
+
+bool Buff_respondTo(entity this, int request)
+{
+    switch (request) {
+        default: return false;
+        case ITEM_SIGNAL(Default):
+            print("Buff responding\n");
+            return true;
+    }
+}
diff --git a/qcsrc/common/items/item/buff.qh b/qcsrc/common/items/item/buff.qh
new file mode 100644 (file)
index 0000000..6b48b1f
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef BUFF_H
+#define BUFF_H
+#include "../item.qh"
+CLASS(Buff, GameItem)
+    METHOD(Buff, respondTo, bool(entity, int))
+ENDCLASS(Buff)
+#endif
diff --git a/qcsrc/common/oo.qh b/qcsrc/common/oo.qh
new file mode 100644 (file)
index 0000000..02f992a
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef OO_H
+#define OO_H
+
+#ifdef MENUQC
+       #define NULL (null_entity)
+#else
+       #define NULL (world)
+#endif
+
+.string classname;
+.string vtblname;
+.entity vtblbase;
+entity spawnVtbl(entity this, entity base)
+{
+       entity vtbl = spawn();
+       copyentity(this, vtbl);
+       vtbl.vtblname = vtbl.classname;
+       vtbl.classname = "vtbl";
+       vtbl.vtblbase = base ? base : vtbl; // Top level objects use vtbl as base
+       return vtbl;
+}
+
+entity Object_vtbl;
+entity spawnObject(entity this, entity)
+{
+       this = spawn();
+       this.classname = "Object";
+       if (!Object_vtbl) Object_vtbl = spawnVtbl(this, NULL);
+       return this;
+}
+
+// Classes have a `spawn##cname(entity, entity)` constructor
+// The parameters are used as locals for [[accumulate]]
+
+// Macro to hide this implementation detail
+#define NEW(cname) (spawn##cname(NULL, NULL))
+
+#define CLASS(cname, base)                                          \
+entity spawn##cname(entity this, entity basevtbl) {                 \
+    this = NEW(base); basevtbl = base##_vtbl;                       \
+}
+
+#define METHOD(cname, name, prototype)                              \
+prototype cname##_##name;                                           \
+.prototype name;                                                    \
+[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {  \
+    this.name = cname##_##name;                                     \
+}
+
+#define ATTRIB(cname, name, type, val)                              \
+.type name;                                                         \
+[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {  \
+    this.name = val;                                                \
+}
+
+#define ATTRIBARRAY(cname, name, type, cnt)                         \
+.type name[cnt];
+
+#define ENDCLASS(cname)                                             \
+.bool instanceOf##cname;                                            \
+entity cname##_vtbl;                                                \
+[[last]] entity spawn##cname(entity this, entity basevtbl) {        \
+    this.instanceOf##cname = true;                                  \
+    this.classname = #cname;                                        \
+    if (!cname##_vtbl) cname##_vtbl = spawnVtbl(this, basevtbl);    \
+    return this;                                                    \
+}
+
+#define SUPER(cname) (cname##_vtbl.vtblbase)
+
+#endif
index 669e08f..50183b9 100644 (file)
@@ -2,6 +2,7 @@
 #include "oo/classes.qc"
 #include "xonotic/util.qh"
 
+#include "../common/items/all.qh"
 #include "../common/weapons/weapons.qh"
 #include "../common/mapinfo.qh"
 
@@ -80,6 +81,7 @@ void m_init()
 
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+       CALL_ACCUMULATED_FUNCTION(RegisterItems);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
 
        RegisterSLCategories();
index 5c74f0d..28b87ab 100644 (file)
@@ -1,71 +1,11 @@
 #ifndef BASE_H
 #define BASE_H
 
+#include "../../common/oo.qh"
+
 #include "../../common/util.qh"
 #include "../../dpdefs/keycodes.qh"
 
-#define NULL (null_entity)
 #define world NULL
 
-.string classname;
-.string vtblname;
-.entity vtblbase;
-entity spawnVtbl(entity this, entity base)
-{
-       entity vtbl = spawn();
-       copyentity(this, vtbl);
-       vtbl.vtblname = vtbl.classname;
-       vtbl.classname = "vtbl";
-       vtbl.vtblbase = base ? base : vtbl; // Top level objects use vtbl as base
-       return vtbl;
-}
-
-entity Object_vtbl;
-entity spawnObject(entity this, entity)
-{
-       this = spawn();
-       this.classname = "Object";
-       if (!Object_vtbl) Object_vtbl = spawnVtbl(this, null_entity);
-       return this;
-}
-
-// Classes have a `spawn##cname(entity, entity)` constructor
-// The parameters are used as locals for [[accumulate]]
-
-// Macro to hide this implementation detail
-#define NEW(cname) (spawn##cname(null_entity, null_entity))
-
-#define CLASS(cname, base)                                          \
-entity spawn##cname(entity this, entity basevtbl) {                 \
-    this = NEW(base); basevtbl = base##_vtbl;                       \
-}
-
-#define METHOD(cname, name, prototype)                              \
-prototype cname##_##name;                                           \
-.prototype name;                                                    \
-[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {  \
-    this.name = cname##_##name;                                     \
-}
-
-#define ATTRIB(cname, name, type, val)                              \
-.type name;                                                         \
-[[accumulate]] entity spawn##cname(entity this, entity basevtbl) {  \
-    this.name = val;                                                \
-}
-
-#define ATTRIBARRAY(cname, name, type, cnt)                         \
-.type name[cnt];
-
-#define ENDCLASS(cname)                                             \
-.bool instanceOf##cname;                                            \
-entity cname##_vtbl;                                                \
-[[last]] entity spawn##cname(entity this, entity basevtbl) {        \
-    this.instanceOf##cname = true;                                  \
-    this.classname = #cname;                                        \
-    if (!cname##_vtbl) cname##_vtbl = spawnVtbl(this, basevtbl);    \
-    return this;                                                    \
-}
-
-#define SUPER(cname) (cname##_vtbl.vtblbase)
-
-#endif
\ No newline at end of file
+#endif
index abfb303..124ac9d 100644 (file)
@@ -21,6 +21,8 @@ xonotic/util.qc
 ../common/urllib.qc
 ../common/util.qc
 
+../common/items/all.qc
+
 ../common/monsters/monsters.qc
 
 ../common/weapons/weapons.qc // TODO
index 82a8177..63f2db8 100644 (file)
@@ -32,6 +32,7 @@
 #include "../common/stats.qh"
 #include "../common/teams.qh"
 #include "../common/util.qh"
+#include "../common/items/all.qh"
 #include "../common/weapons/weapons.qh"
 
 const float LATENCY_THINKRATE = 10;
@@ -556,6 +557,7 @@ void spawnfunc___init_dedicated_server(void)
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
        CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
+       CALL_ACCUMULATED_FUNCTION(RegisterItems);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
@@ -604,6 +606,7 @@ void spawnfunc_worldspawn (void)
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
        CALL_ACCUMULATED_FUNCTION(RegisterMonsters);
+       CALL_ACCUMULATED_FUNCTION(RegisterItems);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
index 20b28a4..0455f6b 100644 (file)
@@ -107,6 +107,9 @@ weapons/weaponsystem.qc
 ../common/test.qc
 ../common/urllib.qc
 ../common/util.qc
+
+../common/items/all.qc
+
 ../common/weapons/config.qc
 ../common/weapons/weapons.qc // TODO