]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
xonogotchi: implement a digital pet minigame
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Sat, 17 Jun 2023 17:44:18 +0000 (19:44 +0200)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Sun, 18 Jun 2023 09:10:14 +0000 (11:10 +0200)
22 files changed:
gfx/hud/default/minigames/xonogotchi/board.tga [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/bowl.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/food.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/food1.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/food2.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/icon.tga [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/icon_notif.tga [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/nest.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/nest2.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/nest2b.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/nest2f.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/nestb.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/nestf.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/pet.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/pet2.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/pet2_r.png [new file with mode: 0644]
gfx/hud/default/minigames/xonogotchi/pet_r.png [new file with mode: 0644]
qcsrc/common/minigames/minigame/_mod.inc
qcsrc/common/minigames/minigame/_mod.qh
qcsrc/common/minigames/minigame/all.qh
qcsrc/common/minigames/minigame/xonogotchi.qc [new file with mode: 0644]
qcsrc/common/minigames/minigame/xonogotchi.qh [new file with mode: 0644]

diff --git a/gfx/hud/default/minigames/xonogotchi/board.tga b/gfx/hud/default/minigames/xonogotchi/board.tga
new file mode 100644 (file)
index 0000000..ad134bc
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/board.tga differ
diff --git a/gfx/hud/default/minigames/xonogotchi/bowl.png b/gfx/hud/default/minigames/xonogotchi/bowl.png
new file mode 100644 (file)
index 0000000..488a2d2
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/bowl.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/food.png b/gfx/hud/default/minigames/xonogotchi/food.png
new file mode 100644 (file)
index 0000000..0b05e76
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/food.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/food1.png b/gfx/hud/default/minigames/xonogotchi/food1.png
new file mode 100644 (file)
index 0000000..8b27a6d
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/food1.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/food2.png b/gfx/hud/default/minigames/xonogotchi/food2.png
new file mode 100644 (file)
index 0000000..700b81e
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/food2.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/icon.tga b/gfx/hud/default/minigames/xonogotchi/icon.tga
new file mode 100644 (file)
index 0000000..49e40ea
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/icon.tga differ
diff --git a/gfx/hud/default/minigames/xonogotchi/icon_notif.tga b/gfx/hud/default/minigames/xonogotchi/icon_notif.tga
new file mode 100644 (file)
index 0000000..9900322
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/icon_notif.tga differ
diff --git a/gfx/hud/default/minigames/xonogotchi/nest.png b/gfx/hud/default/minigames/xonogotchi/nest.png
new file mode 100644 (file)
index 0000000..382bc2b
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/nest.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/nest2.png b/gfx/hud/default/minigames/xonogotchi/nest2.png
new file mode 100644 (file)
index 0000000..c259ec5
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/nest2.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/nest2b.png b/gfx/hud/default/minigames/xonogotchi/nest2b.png
new file mode 100644 (file)
index 0000000..b31ceb6
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/nest2b.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/nest2f.png b/gfx/hud/default/minigames/xonogotchi/nest2f.png
new file mode 100644 (file)
index 0000000..f1d9d0e
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/nest2f.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/nestb.png b/gfx/hud/default/minigames/xonogotchi/nestb.png
new file mode 100644 (file)
index 0000000..be9577a
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/nestb.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/nestf.png b/gfx/hud/default/minigames/xonogotchi/nestf.png
new file mode 100644 (file)
index 0000000..7630562
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/nestf.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/pet.png b/gfx/hud/default/minigames/xonogotchi/pet.png
new file mode 100644 (file)
index 0000000..124892b
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/pet.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/pet2.png b/gfx/hud/default/minigames/xonogotchi/pet2.png
new file mode 100644 (file)
index 0000000..78f0ad5
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/pet2.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/pet2_r.png b/gfx/hud/default/minigames/xonogotchi/pet2_r.png
new file mode 100644 (file)
index 0000000..65b1153
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/pet2_r.png differ
diff --git a/gfx/hud/default/minigames/xonogotchi/pet_r.png b/gfx/hud/default/minigames/xonogotchi/pet_r.png
new file mode 100644 (file)
index 0000000..fab1580
Binary files /dev/null and b/gfx/hud/default/minigames/xonogotchi/pet_r.png differ
index ac39421df163c60dbb12213a3dd731039859e0fc..71d8af39e25e97f2cd1949e29cbe1984c555e7a1 100644 (file)
@@ -6,3 +6,4 @@
 #include <common/minigames/minigame/pp.qc>
 #include <common/minigames/minigame/ps.qc>
 #include <common/minigames/minigame/ttt.qc>
+#include <common/minigames/minigame/xonogotchi.qc>
index fe8378bf13a9b1c1077c38a510018eb6329dd071..928c3df8ab5ca1e61f58e6aecd68a92a240a93da 100644 (file)
@@ -6,3 +6,4 @@
 #include <common/minigames/minigame/pp.qh>
 #include <common/minigames/minigame/ps.qh>
 #include <common/minigames/minigame/ttt.qh>
+#include <common/minigames/minigame/xonogotchi.qh>
index 5bbb7ebbf93473769f6fb742dce0fbed3db58b07..43fd10d0d1d6036a713e50a876f5d152ac4b1e54 100644 (file)
@@ -70,6 +70,7 @@ that .owner is set to the minigame session entity and .minigame_autoclean is tru
 #include "ps.qc"
 #include "pp.qc"
 #include "bd.qc"
+#include "xonogotchi.qc"
 
 /**
  * Set up automatic entity read/write functionality
@@ -102,4 +103,7 @@ that .owner is set to the minigame session entity and .minigame_autoclean is tru
        MSLE(pong_paddle,FIELD(MINIG_SF_CREATE,Byte,team) FIELD(MINIG_SF_CREATE,Float,pong_length) FIELD(MINIG_SF_UPDATE,Vector2D,origin)) \
        MSLE(pong_ball,FIELD(MINIG_SF_CREATE,Float,pong_length) FIELD(PONG_SF_BALLTEAM,Byte,team) FIELD(MINIG_SF_UPDATE, Vector2D, velocity) FIELD(MINIG_SF_UPDATE, Vector2D, origin)) \
        MSLE(pong_ai, FIELD(MINIG_SF_CREATE,Byte,team) FIELD(PONG_SF_PLAYERSCORE, Long, pong_score)) \
+       MSLE(xonogotchi_pet,FIELD(MINIG_SF_UPDATE, Vector2D, origin) FIELD(MINIG_SF_UPDATE, Byte, xonogotchi_pet_movedir) FIELD(MINIG_SF_UPDATE, Float, xonogotchi_pet_level) FIELD(MINIG_SF_UPDATE, Float, xonogotchi_pet_health) FIELD(MINIG_SF_UPDATE, Float, xonogotchi_pet_hunger) FIELD(MINIG_SF_UPDATE, Float, xonogotchi_pet_energy)) \
+       MSLE(xonogotchi_nest,FIELD(MINIG_SF_UPDATE, Vector2D, origin)) \
+       MSLE(xonogotchi_bowl,FIELD(MINIG_SF_UPDATE, Vector2D, origin) FIELD(MINIG_SF_UPDATE, Float, count)) \
        /*empty line*/
diff --git a/qcsrc/common/minigames/minigame/xonogotchi.qc b/qcsrc/common/minigames/minigame/xonogotchi.qc
new file mode 100644 (file)
index 0000000..3e40c98
--- /dev/null
@@ -0,0 +1,549 @@
+#include "xonogotchi.qh"
+REGISTER_MINIGAME(xonogotchi, _("Xonogotchi"));
+
+// minigame flags
+const int XONOGOTCHI_DEAD = 0x0001;
+
+const float XONOGOTCHI_PET_SIZE = 0.25;
+const vector XONOGOTCHI_PET_MAXS = '1 1 0' * XONOGOTCHI_PET_SIZE / 2;
+const vector XONOGOTCHI_PET_MINS = -XONOGOTCHI_PET_MAXS;
+const int XONOGOTCHI_PET_MOVE_LEFT = 0x01;
+const int XONOGOTCHI_PET_MOVE_RIGHT = 0x02;
+
+const float XONOGOTCHI_NEST_SIZE = 0.25;
+const vector XONOGOTCHI_NEST_MAXS = '1 1 0' * XONOGOTCHI_NEST_SIZE / 2;
+const vector XONOGOTCHI_NEST_MINS = -XONOGOTCHI_NEST_MAXS;
+
+const float XONOGOTCHI_BOWL_SIZE = 0.125;
+const vector XONOGOTCHI_BOWL_MAXS = '1 1 0' * XONOGOTCHI_BOWL_SIZE / 2;
+const vector XONOGOTCHI_BOWL_MINS = -XONOGOTCHI_BOWL_MAXS;
+const int XONOGOTCHI_BOWL_FOOD_LEVEL_HIGH = 150;
+const int XONOGOTCHI_BOWL_FOOD_LEVEL_MEDIUM = 50;
+
+const int XONOGOTCHI_TILES = 128;
+const int XONOGOTCHI_STEPS_PER_SECOND = 32;
+const int XONOGOTCHI_STEPS_PER_ANIM = 8;
+
+const float XONOGOTCHI_THINK_DURATION_INITIAL = 0.75;
+const float XONOGOTCHI_THINK_DURATION_JITTER = 3;
+const float XONOGOTCHI_EAT_DURATION = 1;
+const float XONOGOTCHI_SLEEP_DURATION = 2;
+const float XONOGOTCHI_TILE_LENGTH = 1 / XONOGOTCHI_TILES;
+const float XONOGOTCHI_STEP_DURATION = 1 / XONOGOTCHI_STEPS_PER_SECOND;
+const float XONOGOTCHI_ANIM_DURATION = XONOGOTCHI_STEP_DURATION * XONOGOTCHI_STEPS_PER_ANIM;
+
+.entity xonogotchi_pet;
+.entity xonogotchi_nest;
+.entity xonogotchi_bowl;
+
+.int xonogotchi_pet_movedir;
+.float xonogotchi_pet_goal;
+.float xonogotchi_pet_level;
+.float xonogotchi_pet_health;
+.float xonogotchi_pet_hunger;
+.float xonogotchi_pet_energy;
+
+.int count;
+
+#ifdef SVQC
+
+void xonogotchi_pet_think(entity this);
+void xonogotchi_pet_spawn(entity this)
+{
+       this.origin = '0.5 0 0';
+       this.origin.y += XONOGOTCHI_TILE_LENGTH * 2;
+       this.xonogotchi_pet_level = 1;
+       this.xonogotchi_pet_health = 100;
+       this.xonogotchi_pet_hunger = 100;
+       this.xonogotchi_pet_energy = 100;
+       setthink(this, xonogotchi_pet_think);
+       this.nextthink = time + XONOGOTCHI_THINK_DURATION_INITIAL + XONOGOTCHI_THINK_DURATION_JITTER * random();
+       this.SendFlags |= MINIG_SF_UPDATE;
+}
+
+void xonogotchi_nest_spawn(entity this)
+{
+       this.origin = '0.85 0 0';
+       this.origin.y += XONOGOTCHI_TILE_LENGTH;
+       this.SendFlags |= MINIG_SF_UPDATE;
+}
+
+void xonogotchi_bowl_spawn(entity this)
+{
+       this.origin = '0.15 0 0';
+       this.origin.y += XONOGOTCHI_TILE_LENGTH * 2;
+       this.count = 250;
+       this.SendFlags |= MINIG_SF_UPDATE;
+}
+
+void xonogotchi_pet_walkthink(entity this);
+void xonogotchi_pet_think(entity this)
+{
+       entity minigame = this.owner;
+       entity bowl = minigame.xonogotchi_bowl;
+       float energy_goal = minigame.xonogotchi_nest.origin.x;
+       float hunger_goal = minigame.xonogotchi_bowl.origin.x;
+       bool want_sleep = (this.xonogotchi_pet_energy < 10);
+       bool want_food = !want_sleep && (this.xonogotchi_pet_hunger < 10) && bowl.count;
+
+       setthink(this, xonogotchi_pet_walkthink);
+       this.nextthink = time;
+       if(!want_sleep && !want_food)
+               this.xonogotchi_pet_goal = bound(0 - XONOGOTCHI_PET_MINS.x, floor(random() * XONOGOTCHI_TILES) / XONOGOTCHI_TILES, 1 - XONOGOTCHI_PET_MAXS.x);
+       else if(want_sleep)
+               this.xonogotchi_pet_goal = energy_goal;
+       else
+               this.xonogotchi_pet_goal = hunger_goal;
+
+       if(this.xonogotchi_pet_goal < this.origin.x)
+               this.xonogotchi_pet_movedir = XONOGOTCHI_PET_MOVE_LEFT;
+       else
+               this.xonogotchi_pet_movedir = XONOGOTCHI_PET_MOVE_RIGHT;
+       this.SendFlags |= MINIG_SF_UPDATE;
+}
+
+void xonogotchi_pet_sleepthink(entity this);
+void xonogotchi_pet_eatthink(entity this);
+void xonogotchi_pet_diethink(entity this);
+void xonogotchi_pet_walkthink(entity this)
+{
+       entity minigame = this.owner;
+       entity bowl = minigame.xonogotchi_bowl;
+       float energy_goal = minigame.xonogotchi_nest.origin.x;
+       float hunger_goal = minigame.xonogotchi_bowl.origin.x;
+       bool want_sleep = (this.xonogotchi_pet_energy < 10);
+       bool want_food = !want_sleep && (this.xonogotchi_pet_hunger < 10) && bowl.count;
+
+       this.xonogotchi_pet_level += 0.001;
+
+       bool goal_reached = false;
+       switch(this.xonogotchi_pet_movedir)
+       {
+               case XONOGOTCHI_PET_MOVE_LEFT:
+                       if(this.xonogotchi_pet_goal < this.origin.x)
+                       {
+                               this.origin.x = bound(0 - XONOGOTCHI_PET_MINS.x, this.origin.x - XONOGOTCHI_TILE_LENGTH, 1 - XONOGOTCHI_PET_MAXS.x);
+                       }
+                       else
+                       {
+                               goal_reached = true;
+                       }
+                       break;
+               case XONOGOTCHI_PET_MOVE_RIGHT:
+                       if(this.xonogotchi_pet_goal > this.origin.x)
+                       {
+                               this.origin.x = bound(0 - XONOGOTCHI_PET_MINS.x, this.origin.x + XONOGOTCHI_TILE_LENGTH, 1 - XONOGOTCHI_PET_MAXS.x);
+                       }
+                       else
+                       {
+                               goal_reached = true;
+                       }
+                       break;
+       }
+
+       this.xonogotchi_pet_energy = max(0, this.xonogotchi_pet_energy - random() * 0.025);
+
+       if(want_sleep && (this.xonogotchi_pet_goal != energy_goal))
+       {
+               goal_reached = false;
+               setthink(this, xonogotchi_pet_think);
+       }
+
+       if(goal_reached)
+               this.xonogotchi_pet_hunger = max(0, this.xonogotchi_pet_hunger - floor(random() * 5));
+
+       if(want_food && (this.xonogotchi_pet_goal != hunger_goal))
+       {
+               goal_reached = false;
+               setthink(this, xonogotchi_pet_think);
+       }
+
+       if(goal_reached)
+       {
+               this.xonogotchi_pet_movedir = 0;
+
+               if(!want_sleep && !want_food)
+               {
+                       setthink(this, xonogotchi_pet_think);
+                       this.nextthink = time + XONOGOTCHI_THINK_DURATION_JITTER * random();
+               }
+               else if(want_sleep)
+               {
+                       setthink(this, xonogotchi_pet_sleepthink);
+                       this.nextthink = time;
+               }
+               else
+               {
+                       setthink(this, xonogotchi_pet_eatthink);
+                       this.nextthink = time;
+               }
+       }
+       else
+       {
+               this.nextthink = time + XONOGOTCHI_STEP_DURATION;
+       }
+
+       if(!this.xonogotchi_pet_hunger)
+               this.xonogotchi_pet_health = max(0, this.xonogotchi_pet_health - random() * 0.25);
+
+       if(!this.xonogotchi_pet_health)
+       {
+               minigame.minigame_flags |= XONOGOTCHI_DEAD;
+               minigame.SendFlags |= MINIG_SF_UPDATE;
+               setthink(this, xonogotchi_pet_diethink);
+               this.nextthink = time;
+       }
+
+       this.SendFlags |= MINIG_SF_UPDATE;
+}
+
+void xonogotchi_pet_sleepthink(entity this)
+{
+       this.xonogotchi_pet_energy = min(100, this.xonogotchi_pet_energy + 1);
+       if(this.xonogotchi_pet_hunger)
+               this.xonogotchi_pet_health = min(100, this.xonogotchi_pet_health + random() * 5);
+
+       if(this.xonogotchi_pet_energy == 100)
+               setthink(this, xonogotchi_pet_think);
+
+       this.nextthink = time + XONOGOTCHI_SLEEP_DURATION;
+       this.SendFlags |= MINIG_SF_UPDATE;
+}
+
+void xonogotchi_pet_eatthink(entity this)
+{
+       entity minigame = this.owner;
+       entity bowl = minigame.xonogotchi_bowl;
+
+       if(bowl.count)
+       {
+               this.xonogotchi_pet_hunger = min(100, this.xonogotchi_pet_hunger + 5);
+               bowl.count -= 5;
+
+               if(this.xonogotchi_pet_hunger == 100)
+                       setthink(this, xonogotchi_pet_think);
+
+               bowl.SendFlags |= MINIG_SF_UPDATE;
+       }
+       else
+       {
+               setthink(this, xonogotchi_pet_think);
+       }
+
+       this.nextthink = time + XONOGOTCHI_EAT_DURATION;
+       this.SendFlags |= MINIG_SF_UPDATE;
+}
+
+void xonogotchi_pet_diethink(entity this)
+{
+}
+
+// required function, handle server side events
+int xonogotchi_server_event(entity minigame, string event, ...)
+{
+       switch(event)
+       {
+               case "start":
+               {
+                       entity pet = msle_spawn(minigame,new(xonogotchi_pet));
+                       xonogotchi_pet_spawn(pet);
+
+                       entity nest = msle_spawn(minigame,new(xonogotchi_nest));
+                       xonogotchi_nest_spawn(nest);
+
+                       entity bowl = msle_spawn(minigame,new(xonogotchi_bowl));
+                       xonogotchi_bowl_spawn(bowl);
+
+                       minigame.xonogotchi_pet = pet;
+                       minigame.xonogotchi_nest = nest;
+                       minigame.xonogotchi_bowl = bowl;
+                       return true;
+               }
+               case "join":
+               {
+                       return 1;
+               }
+               case "cmd":
+               {
+                       switch(argv(0))
+                       {
+                               case "refill":
+                                       entity bowl = minigame.xonogotchi_bowl;
+
+                                       bowl.count = 250;
+                                       bowl.SendFlags |= MINIG_SF_UPDATE;
+                                       return true;
+                               //case "shop":
+                               //      return true;
+                       }
+                       return false;
+               }
+       }
+
+       return false;
+}
+
+#elif defined(CSQC)
+
+const int XONOGOTCHI_PET_ANIM_WALK = 0x01;
+const int XONOGOTCHI_PET_ANIM_LEFT = 0x02;
+const int XONOGOTCHI_PET_ANIM_RIGHT = 0x04;
+
+.float anim_time;
+.int anim_state;
+
+// Required function, draw the game board
+void xonogotchi_hud_board(vector pos, vector mySize)
+{
+       minigame_hud_fitsqare(pos, mySize);
+       minigame_hud_simpleboard(pos,mySize,minigame_texture("xonogotchi/board"));
+
+       entity e;
+       vector org;
+       vector obj_pos;
+       vector obj_size;
+       FOREACH_MINIGAME_ENTITY(e)
+       {
+               switch(e.classname)
+               {
+                       case "xonogotchi_nest":
+                       {
+                               org = e.origin;
+                               org.y -= XONOGOTCHI_NEST_MINS.y;
+                               org.y = 1 - org.y;
+                               obj_size = minigame_hud_denormalize_size('1 1 0'*XONOGOTCHI_NEST_SIZE,pos,mySize);
+                               obj_pos = minigame_hud_denormalize(org,pos,mySize);
+
+                               minigame_drawpic_centered( obj_pos, minigame_texture("xonogotchi/nest2b"),
+                                               obj_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
+                               break;
+                       }
+                       case "xonogotchi_bowl":
+                       {
+                               org = e.origin;
+                               org.y -= XONOGOTCHI_BOWL_MINS.y;
+                               org.y = 1 - org.y;
+                               obj_size = minigame_hud_denormalize_size('1 1 0'*XONOGOTCHI_BOWL_SIZE,pos,mySize);
+                               obj_pos = minigame_hud_denormalize(org,pos,mySize);
+
+                               string food_texture = string_null;
+                               if(e.count >= XONOGOTCHI_BOWL_FOOD_LEVEL_HIGH)
+                                       food_texture = "xonogotchi/food";
+                               else if(e.count >= XONOGOTCHI_BOWL_FOOD_LEVEL_MEDIUM)
+                                       food_texture = "xonogotchi/food1";
+                               else if(e.count)
+                                       food_texture = "xonogotchi/food2";
+
+                               if(food_texture)
+                                       minigame_drawpic_centered( obj_pos, minigame_texture(food_texture),
+                                                       obj_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
+                               minigame_drawpic_centered( obj_pos, minigame_texture("xonogotchi/bowl"),
+                                               obj_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
+                               break;
+                       }
+               }
+       }
+
+       FOREACH_MINIGAME_ENTITY(e)
+       {
+               if ( e.classname == "xonogotchi_pet" )
+               {
+                       if(!e.xonogotchi_pet_health)
+                               break;
+
+                       if(!e.anim_time || time > e.anim_time + XONOGOTCHI_ANIM_DURATION)
+                       {
+                               switch(e.xonogotchi_pet_movedir)
+                               {
+                                       case XONOGOTCHI_PET_MOVE_LEFT:
+                                       case XONOGOTCHI_PET_MOVE_RIGHT:
+                                               e.anim_time = time;
+                                               e.anim_state ^= XONOGOTCHI_PET_ANIM_WALK;
+                                               break;
+                                       default:
+                                               e.anim_time = 0;
+                                               e.anim_state &= ~XONOGOTCHI_PET_ANIM_WALK;
+                               }
+                       }
+
+                       switch(e.xonogotchi_pet_movedir)
+                       {
+                               case XONOGOTCHI_PET_MOVE_LEFT:
+                                       e.anim_state |= XONOGOTCHI_PET_ANIM_LEFT;
+                                       e.anim_state &= ~XONOGOTCHI_PET_ANIM_RIGHT;
+                                       break;
+                               case XONOGOTCHI_PET_MOVE_RIGHT:
+                                       e.anim_state |= XONOGOTCHI_PET_ANIM_RIGHT;
+                                       e.anim_state &= ~XONOGOTCHI_PET_ANIM_LEFT;
+                                       break;
+                       }
+
+                       string anim_texture;
+                       if(!(e.anim_state & XONOGOTCHI_PET_ANIM_WALK))
+                               anim_texture = "xonogotchi/pet";
+                       else
+                               anim_texture = "xonogotchi/pet2";
+
+                       org = e.origin;
+                       org.y -= XONOGOTCHI_PET_MINS.y;
+                       org.y = 1 - org.y;
+                       obj_size = minigame_hud_denormalize_size('1 1 0'*XONOGOTCHI_PET_SIZE,pos,mySize);
+                       obj_pos = minigame_hud_denormalize(org,pos,mySize);
+
+                       if(e.anim_state & XONOGOTCHI_PET_ANIM_RIGHT)
+                               anim_texture = strcat(anim_texture, "_r");
+
+                       minigame_drawpic_centered( obj_pos, minigame_texture(anim_texture),
+                                       obj_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
+               }
+       }
+
+       FOREACH_MINIGAME_ENTITY(e)
+       {
+               if ( e.classname == "xonogotchi_nest" )
+               {
+                       org = e.origin;
+                       org.y -= XONOGOTCHI_NEST_MINS.y;
+                       org.y = 1 - org.y;
+                       obj_size = minigame_hud_denormalize_size('1 1 0'*XONOGOTCHI_NEST_SIZE,pos,mySize);
+                       obj_pos = minigame_hud_denormalize(org,pos,mySize);
+
+                       minigame_drawpic_centered( obj_pos, minigame_texture("xonogotchi/nest2f"),
+                                       obj_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
+               }
+       }
+}
+
+// Required function, draw the game status panel
+void xonogotchi_hud_status(vector pos, vector mySize)
+{
+       HUD_Panel_DrawBg();
+       vector ts;
+       ts = minigame_drawstring_wrapped(mySize.x,pos,active_minigame.descriptor.message,
+               hud_fontsize * 2, '0.25 0.47 0.72', panel_fg_alpha, DRAWFLAG_NORMAL,0.5);
+       ts.y += hud_fontsize.y;
+       pos.y += ts.y;
+       mySize.y -= ts.y;
+
+       vector player_fontsize = hud_fontsize * 1.75;
+       ts.y = ( mySize.y - PONG_MAX_PLAYERS*player_fontsize.y ) / 1;
+       ts.x = mySize.x;
+       vector mypos;
+
+       entity e;
+       entity pet = NULL;
+       FOREACH_MINIGAME_ENTITY(e)
+       {
+               if ( e.classname == "xonogotchi_pet" )
+                       pet = e;
+       }
+
+       if(!pet)
+               return;
+
+       FOREACH_MINIGAME_ENTITY(e)
+       {
+               if ( e.classname == "minigame_player" )
+               {
+                       mypos = pos;
+                       minigame_drawcolorcodedstring_trunc(mySize_x,mypos,
+                               entcs_GetName(e.minigame_playerslot-1),
+                               player_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y;
+
+                       drawstring(mypos,_("Level"),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y;
+
+                       drawstring(mypos,sprintf(_("%s"), ftos(floor(pet.xonogotchi_pet_level))),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y * 2;
+
+                       drawstring(mypos,_("Health"),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y;
+
+                       drawstring(mypos,sprintf(_("%s%%"), ftos(ceil(pet.xonogotchi_pet_health))),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y * 2;
+
+                       drawstring(mypos,_("Hunger"),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y;
+
+                       drawstring(mypos,sprintf(_("%s%%"), ftos(pet.xonogotchi_pet_hunger)),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y * 2;
+
+                       drawstring(mypos,_("Energy"),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+
+                       mypos_y += player_fontsize_y;
+
+                       drawstring(mypos,sprintf(_("%s%%"), ftos(ceil(pet.xonogotchi_pet_energy))),'28 28 0',
+                                          '0.7 0.84 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               }
+       }
+}
+
+// convert minigame flags to a message
+string xonogotchi_message(int mgflags)
+{
+       string rmessage = "";
+       if (mgflags & XONOGOTCHI_DEAD)
+               rmessage = _("Your bird died");
+       return rmessage;
+}
+
+// Required function, handle client events
+int xonogotchi_client_event(entity minigame, string event, ...)
+{
+       switch(event)
+       {
+               case "activate":
+                       return false;
+               case "deactivate":
+               {
+                       strfree(minigame.message);
+                       return false;
+               }
+               case "network_receive":
+               {
+                       entity sent = ...(0,entity);
+                       int sf = ...(1,int);
+                       if ( sent.classname == "minigame" )
+                       {
+                               if ( sf & MINIG_SF_UPDATE )
+                               {
+                                       strcpy(sent.message, xonogotchi_message(sent.minigame_flags));
+                               }
+                       }
+                       return false;
+               }
+               case "menu_show":
+                       HUD_MinigameMenu_CustomEntry(...(0,entity),_("Refill Food"),"refill");
+                       //HUD_MinigameMenu_CustomEntry(...(0,entity),_("Shop"),"shop");
+                       return false;
+               case "menu_click":
+                       switch(...(0,string))
+                       {
+                               case "refill":
+                                       minigame_cmd("refill");
+                                       break;
+                               //case "shop":
+                               //      break;
+                       }
+                       return false;
+       }
+
+       return false;
+}
+
+#endif
diff --git a/qcsrc/common/minigames/minigame/xonogotchi.qh b/qcsrc/common/minigames/minigame/xonogotchi.qh
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once