summaryrefslogtreecommitdiffstats
path: root/src/jake2/game/GameUtilAdapters.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jake2/game/GameUtilAdapters.java')
-rw-r--r--src/jake2/game/GameUtilAdapters.java652
1 files changed, 652 insertions, 0 deletions
diff --git a/src/jake2/game/GameUtilAdapters.java b/src/jake2/game/GameUtilAdapters.java
new file mode 100644
index 0000000..4a3c320
--- /dev/null
+++ b/src/jake2/game/GameUtilAdapters.java
@@ -0,0 +1,652 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+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; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; 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.
+
+*/
+
+// Created on 26.02.2004 by RST.
+// $Id: GameUtilAdapters.java,v 1.1 2004-07-08 15:58:44 hzi Exp $
+
+package jake2.game;
+
+import jake2.*;
+import jake2.qcommon.Com;
+import jake2.util.*;
+
+public class GameUtilAdapters
+{
+
+ public static EntThinkAdapter Think_Delay = new EntThinkAdapter()
+ {
+ public boolean think(edict_t ent)
+ {
+ GameUtil.G_UseTargets(ent, ent.activator);
+ GameUtil.G_FreeEdict(ent);
+ return true;
+ }
+ };
+ public static EntThinkAdapter G_FreeEdictA = new EntThinkAdapter()
+ {
+ public boolean think(edict_t ent)
+ {
+ GameUtil.G_FreeEdict(ent);
+ return false;
+ }
+ };
+ static EntThinkAdapter MegaHealth_think = new EntThinkAdapter()
+ {
+ public boolean think(edict_t self)
+ {
+ if (self.owner.health > self.owner.max_health)
+ {
+ self.nextthink = GameBase.level.time + 1;
+ self.owner.health -= 1;
+ return false;
+ }
+
+ if (!((self.spawnflags & Defines.DROPPED_ITEM) != 0) && (GameBase.deathmatch.value != 0))
+ GameUtil.SetRespawn(self, 20);
+ else
+ GameUtil.G_FreeEdict(self);
+
+ return false;
+ }
+ };
+ static EntThinkAdapter DoRespawn = new EntThinkAdapter()
+ {
+ public boolean think(edict_t ent)
+ {
+ if (ent.team != null)
+ {
+ edict_t master;
+ int count;
+ int choice = 0;
+
+ master = ent.teammaster;
+
+ // tiefe z�hlen
+ // count the depth
+ for (count = 0, ent = master; ent != null; ent = ent.chain, count++);
+
+ choice = Lib.rand() % count;
+
+ for (count = 0, ent = master; count < choice; ent = ent.chain, count++);
+ }
+
+ ent.svflags &= ~Defines.SVF_NOCLIENT;
+ ent.solid = Defines.SOLID_TRIGGER;
+ GameBase.gi.linkentity(ent);
+
+ // send an effect
+ ent.s.event = Defines.EV_ITEM_RESPAWN;
+
+ return false;
+ }
+ };
+ static EntInteractAdapter Pickup_Pack = new EntInteractAdapter()
+ {
+ public boolean interact(edict_t ent, edict_t other)
+ {
+
+ gitem_t item;
+ int index;
+
+ if (other.client.pers.max_bullets < 300)
+ other.client.pers.max_bullets = 300;
+ if (other.client.pers.max_shells < 200)
+ other.client.pers.max_shells = 200;
+ if (other.client.pers.max_rockets < 100)
+ other.client.pers.max_rockets = 100;
+ if (other.client.pers.max_grenades < 100)
+ other.client.pers.max_grenades = 100;
+ if (other.client.pers.max_cells < 300)
+ other.client.pers.max_cells = 300;
+ if (other.client.pers.max_slugs < 100)
+ other.client.pers.max_slugs = 100;
+
+ item = GameUtil.FindItem("Bullets");
+ if (item != null)
+ {
+ index = GameUtil.ITEM_INDEX(item);
+ other.client.pers.inventory[index] += item.quantity;
+ if (other.client.pers.inventory[index] > other.client.pers.max_bullets)
+ other.client.pers.inventory[index] = other.client.pers.max_bullets;
+ }
+
+ item = GameUtil.FindItem("Shells");
+ if (item != null)
+ {
+ index = GameUtil.ITEM_INDEX(item);
+ other.client.pers.inventory[index] += item.quantity;
+ if (other.client.pers.inventory[index] > other.client.pers.max_shells)
+ other.client.pers.inventory[index] = other.client.pers.max_shells;
+ }
+
+ item = GameUtil.FindItem("Cells");
+ if (item != null)
+ {
+ index = GameUtil.ITEM_INDEX(item);
+ other.client.pers.inventory[index] += item.quantity;
+ if (other.client.pers.inventory[index] > other.client.pers.max_cells)
+ other.client.pers.inventory[index] = other.client.pers.max_cells;
+ }
+
+ item = GameUtil.FindItem("Grenades");
+ if (item != null)
+ {
+ index = GameUtil.ITEM_INDEX(item);
+ other.client.pers.inventory[index] += item.quantity;
+ if (other.client.pers.inventory[index] > other.client.pers.max_grenades)
+ other.client.pers.inventory[index] = other.client.pers.max_grenades;
+ }
+
+ item = GameUtil.FindItem("Rockets");
+ if (item != null)
+ {
+ index = GameUtil.ITEM_INDEX(item);
+ other.client.pers.inventory[index] += item.quantity;
+ if (other.client.pers.inventory[index] > other.client.pers.max_rockets)
+ other.client.pers.inventory[index] = other.client.pers.max_rockets;
+ }
+
+ item = GameUtil.FindItem("Slugs");
+ if (item != null)
+ {
+ index = GameUtil.ITEM_INDEX(item);
+ other.client.pers.inventory[index] += item.quantity;
+ if (other.client.pers.inventory[index] > other.client.pers.max_slugs)
+ other.client.pers.inventory[index] = other.client.pers.max_slugs;
+ }
+
+ if (0 == (ent.spawnflags & Defines.DROPPED_ITEM) && (GameBase.deathmatch.value != 0))
+ GameUtil.SetRespawn(ent, ent.item.quantity);
+
+ return true;
+ }
+ };
+ final static EntInteractAdapter Pickup_Health = new EntInteractAdapter()
+ {
+ public boolean interact(edict_t ent, edict_t other)
+ {
+
+ if (0 == (ent.style & Defines.HEALTH_IGNORE_MAX))
+ if (other.health >= other.max_health)
+ return false;
+
+ other.health += ent.count;
+
+ if (0 == (ent.style & Defines.HEALTH_IGNORE_MAX))
+ {
+ if (other.health > other.max_health)
+ other.health = other.max_health;
+ }
+
+ if (0 != (ent.style & Defines.HEALTH_TIMED))
+ {
+ ent.think = MegaHealth_think;
+ ent.nextthink = GameBase.level.time + 5f;
+ ent.owner = other;
+ ent.flags |= Defines.FL_RESPAWN;
+ ent.svflags |= Defines.SVF_NOCLIENT;
+ ent.solid = Defines.SOLID_NOT;
+ }
+ else
+ {
+ if (!((ent.spawnflags & Defines.DROPPED_ITEM) != 0) && (GameBase.deathmatch.value != 0))
+ GameUtil.SetRespawn(ent, 30);
+ }
+
+ return true;
+ }
+
+ };
+ /*
+ ===============
+ Touch_Item
+ ===============
+ */
+
+ static EntTouchAdapter Touch_Item = new EntTouchAdapter()
+ {
+ public void touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf)
+ {
+ boolean taken;
+
+ if (ent.classname.equals("item_breather"))
+ taken = false;
+
+
+ if (other.client == null)
+ return;
+ if (other.health < 1)
+ return; // dead people can't pickup
+ if (ent.item.pickup == null)
+ return; // not a grabbable item?
+
+
+ taken = ent.item.pickup.interact(ent, other);
+
+ if (taken)
+ {
+ // flash the screen
+ other.client.bonus_alpha = 0.25f;
+
+ // show icon and name on status bar
+ other.client.ps.stats[Defines.STAT_PICKUP_ICON] = (short) GameBase.gi.imageindex(ent.item.icon);
+ other.client.ps.stats[Defines.STAT_PICKUP_STRING] = (short) (Defines.CS_ITEMS + GameUtil.ITEM_INDEX(ent.item));
+ other.client.pickup_msg_time = GameBase.level.time + 3.0f;
+
+ // change selected item
+ if (ent.item.use != null)
+ other.client.pers.selected_item =
+ other.client.ps.stats[Defines.STAT_SELECTED_ITEM] = (short) GameUtil.ITEM_INDEX(ent.item);
+
+ if (ent.item.pickup == Pickup_Health)
+ {
+ if (ent.count == 2)
+ GameBase.gi.sound(
+ other,
+ Defines.CHAN_ITEM,
+ GameBase.gi.soundindex("items/s_health.wav"),
+ 1,
+ Defines.ATTN_NORM,
+ 0);
+ else if (ent.count == 10)
+ GameBase.gi.sound(
+ other,
+ Defines.CHAN_ITEM,
+ GameBase.gi.soundindex("items/n_health.wav"),
+ 1,
+ Defines.ATTN_NORM,
+ 0);
+ else if (ent.count == 25)
+ GameBase.gi.sound(
+ other,
+ Defines.CHAN_ITEM,
+ GameBase.gi.soundindex("items/l_health.wav"),
+ 1,
+ Defines.ATTN_NORM,
+ 0);
+ else // (ent.count == 100)
+ GameBase.gi.sound(
+ other,
+ Defines.CHAN_ITEM,
+ GameBase.gi.soundindex("items/m_health.wav"),
+ 1,
+ Defines.ATTN_NORM,
+ 0);
+ }
+ else if (ent.item.pickup_sound != null)
+ {
+ GameBase.gi.sound(
+ other,
+ Defines.CHAN_ITEM,
+ GameBase.gi.soundindex(ent.item.pickup_sound),
+ 1,
+ Defines.ATTN_NORM,
+ 0);
+ }
+ }
+
+ if (0 == (ent.spawnflags & Defines.ITEM_TARGETS_USED))
+ {
+ GameUtil.G_UseTargets(ent, other);
+ ent.spawnflags |= Defines.ITEM_TARGETS_USED;
+ }
+
+ if (!taken)
+ return;
+ Com.p("Picked up:" + ent.classname);
+
+ if (!((GameBase.coop.value != 0) && (ent.item.flags & Defines.IT_STAY_COOP) != 0)
+ || 0 != (ent.spawnflags & (Defines.DROPPED_ITEM | Defines.DROPPED_PLAYER_ITEM)))
+ {
+ if ((ent.flags & Defines.FL_RESPAWN) != 0)
+ ent.flags &= ~Defines.FL_RESPAWN;
+ else
+ GameUtil.G_FreeEdict(ent);
+ }
+ }
+ };
+ static EntTouchAdapter drop_temp_touch = new EntTouchAdapter()
+ {
+ public void touch(edict_t ent, edict_t other, cplane_t plane, csurface_t surf)
+ {
+ if (other == ent.owner)
+ return;
+
+ Touch_Item.touch(ent, other, plane, surf);
+ }
+ };
+ static EntThinkAdapter drop_make_touchable = new EntThinkAdapter()
+ {
+ public boolean think(edict_t ent)
+ {
+ ent.touch = Touch_Item;
+ if (GameBase.deathmatch.value != 0)
+ {
+ ent.nextthink = GameBase.level.time + 29;
+ ent.think = G_FreeEdictA;
+ }
+ return false;
+ }
+ };
+ static int quad_drop_timeout_hack = 0;
+ static ItemUseAdapter Use_Quad = new ItemUseAdapter()
+ {
+
+ public void use(edict_t ent, gitem_t item)
+ {
+ int timeout;
+
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]--;
+ GameUtil.ValidateSelectedItem(ent);
+
+ if (quad_drop_timeout_hack != 0)
+ {
+ timeout = quad_drop_timeout_hack;
+ quad_drop_timeout_hack = 0;
+ }
+ else
+ {
+ timeout = 300;
+ }
+
+ if (ent.client.quad_framenum > GameBase.level.framenum)
+ ent.client.quad_framenum += timeout;
+ else
+ ent.client.quad_framenum = GameBase.level.framenum + timeout;
+
+ GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/damage.wav"), 1, Defines.ATTN_NORM, 0);
+ }
+ };
+ static ItemUseAdapter Use_Invulnerability = new ItemUseAdapter()
+ {
+ public void use(edict_t ent, gitem_t item)
+ {
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]--;
+ GameUtil.ValidateSelectedItem(ent);
+
+ if (ent.client.invincible_framenum > GameBase.level.framenum)
+ ent.client.invincible_framenum += 300;
+ else
+ ent.client.invincible_framenum = GameBase.level.framenum + 300;
+
+ GameBase.gi.sound(ent, Defines.CHAN_ITEM, GameBase.gi.soundindex("items/protect.wav"), 1, Defines.ATTN_NORM, 0);
+ }
+ };
+ // ======================================================================
+
+ static ItemUseAdapter Use_Breather = new ItemUseAdapter()
+ {
+ public void use(edict_t ent, gitem_t item)
+ {
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]--;
+
+ //TODO: remove this line
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]=0;
+
+ GameUtil.ValidateSelectedItem(ent);
+
+ if (ent.client.breather_framenum > GameBase.level.framenum)
+ ent.client.breather_framenum += 300;
+ else
+ ent.client.breather_framenum = GameBase.level.framenum + 300;
+
+ // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
+ }
+ };
+ // ======================================================================
+
+ static ItemUseAdapter Use_Envirosuit = new ItemUseAdapter()
+ {
+ public void use(edict_t ent, gitem_t item)
+ {
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]--;
+ GameUtil.ValidateSelectedItem(ent);
+
+ if (ent.client.enviro_framenum > GameBase.level.framenum)
+ ent.client.enviro_framenum += 300;
+ else
+ ent.client.enviro_framenum = GameBase.level.framenum + 300;
+
+ // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
+ }
+ };
+ // ======================================================================
+ /*
+ static ItemUseAdapter Use_Invulnerability = new ItemUseAdapter()
+ {
+ public void use(edict_t ent, gitem_t item)
+ {
+
+ ent.client.pers.inventory[ITEM_INDEX(item)]--;
+ ValidateSelectedItem(ent);
+
+ if (ent.client.invincible_framenum > level.framenum)
+ ent.client.invincible_framenum += 300;
+ else
+ ent.client.invincible_framenum = level.framenum + 300;
+
+ gi.sound(ent, CHAN_ITEM, gi.soundindex("items/protect.wav"), 1, ATTN_NORM, 0);
+ }
+ };
+ */
+
+ // ======================================================================
+
+ static ItemUseAdapter Use_Silencer = new ItemUseAdapter()
+ {
+ public void use(edict_t ent, gitem_t item)
+ {
+
+ ent.client.pers.inventory[GameUtil.ITEM_INDEX(item)]--;
+ GameUtil.ValidateSelectedItem(ent);
+ ent.client.silencer_shots += 30;
+
+ // gi.sound(ent, CHAN_ITEM, gi.soundindex("items/damage.wav"), 1, ATTN_NORM, 0);
+ }
+ };
+ // ======================================================================
+
+ static EntInteractAdapter Pickup_Key = new EntInteractAdapter()
+ {
+ public boolean interact(edict_t ent, edict_t other)
+ {
+ if (GameBase.coop.value != 0)
+ {
+ if (Lib.strcmp(ent.classname, "key_power_cube") == 0)
+ {
+ if ((other.client.pers.power_cubes & ((ent.spawnflags & 0x0000ff00) >> 8)) != 0)
+ return false;
+ other.client.pers.inventory[GameUtil.ITEM_INDEX(ent.item)]++;
+ other.client.pers.power_cubes |= ((ent.spawnflags & 0x0000ff00) >> 8);
+ }
+ else
+ {
+ if (other.client.pers.inventory[GameUtil.ITEM_INDEX(ent.item)] != 0)
+ return false;
+ other.client.pers.inventory[GameUtil.ITEM_INDEX(ent.item)] = 1;
+ }
+ return true;
+ }
+ other.client.pers.inventory[GameUtil.ITEM_INDEX(ent.item)]++;
+ return true;
+ }
+ };
+ static int jacket_armor_index;
+ static int combat_armor_index;
+ static int body_armor_index;
+ static int power_screen_index;
+ static int power_shield_index;
+ /*
+ =============
+ range
+
+ returns the range catagorization of an entity reletive to self.
+ 0 melee range, will become hostile even if back is turned
+ 1 visibility and infront, or visibility and show hostile
+ 2 infront and show hostile
+ 3 only triggered by damage
+
+ */
+ // static int range(edict_t self, edict_t other)
+ // {
+ // float[] v= { 0, 0, 0 };
+ // float len;
+ //
+ // VectorSubtract(self.s.origin, other.s.origin, v);
+ // len= VectorLength(v);
+ // if (len < MELEE_DISTANCE)
+ // return RANGE_MELEE;
+ // if (len < 500)
+ // return RANGE_NEAR;
+ // if (len < 1000)
+ // return RANGE_MID;
+ // return RANGE_FAR;
+ // }
+
+ // ============================================================================
+
+ static EntThinkAdapter M_CheckAttack = new EntThinkAdapter()
+ {
+
+ public boolean think(edict_t self)
+ {
+ float[] spot1 = { 0, 0, 0 };
+
+ float[] spot2 = { 0, 0, 0 };
+ float chance;
+ trace_t tr;
+
+ if (self.enemy.health > 0)
+ {
+ // see if any entities are in the way of the shot
+ Math3D.VectorCopy(self.s.origin, spot1);
+ spot1[2] += self.viewheight;
+ Math3D.VectorCopy(self.enemy.s.origin, spot2);
+ spot2[2] += self.enemy.viewheight;
+
+ tr =
+ GameBase.gi.trace(
+ spot1,
+ null,
+ null,
+ spot2,
+ self,
+ Defines.CONTENTS_SOLID
+ | Defines.CONTENTS_MONSTER
+ | Defines.CONTENTS_SLIME
+ | Defines.CONTENTS_LAVA
+ | Defines.CONTENTS_WINDOW);
+
+ // do we have a clear shot?
+ if (tr.ent != self.enemy)
+ return false;
+ }
+
+ // melee attack
+ if (enemy_range == Defines.RANGE_MELEE)
+ {
+ // don't always melee in easy mode
+ if (GameBase.skill.value == 0 && (Lib.rand() & 3) != 0)
+ return false;
+ if (self.monsterinfo.melee != null)
+ self.monsterinfo.attack_state = Defines.AS_MELEE;
+ else
+ self.monsterinfo.attack_state = Defines.AS_MISSILE;
+ return true;
+ }
+
+ // missile attack
+ if (self.monsterinfo.attack == null)
+ return false;
+
+ if (GameBase.level.time < self.monsterinfo.attack_finished)
+ return false;
+
+ if (enemy_range == Defines.RANGE_FAR)
+ return false;
+
+ if ((self.monsterinfo.aiflags & Defines.AI_STAND_GROUND) != 0)
+ {
+ chance = 0.4f;
+ }
+ else if (enemy_range == Defines.RANGE_MELEE)
+ {
+ chance = 0.2f;
+ }
+ else if (enemy_range == Defines.RANGE_NEAR)
+ {
+ chance = 0.1f;
+ }
+ else if (enemy_range == Defines.RANGE_MID)
+ {
+ chance = 0.02f;
+ }
+ else
+ {
+ return false;
+ }
+
+ if (GameBase.skill.value == 0)
+ chance *= 0.5;
+ else if (GameBase.skill.value >= 2)
+ chance *= 2;
+
+ if (Lib.random() < chance)
+ {
+ self.monsterinfo.attack_state = Defines.AS_MISSILE;
+ self.monsterinfo.attack_finished = GameBase.level.time + 2 * Lib.random();
+ return true;
+ }
+
+ if ((self.flags & Defines.FL_FLY) != 0)
+ {
+ if (Lib.random() < 0.3f)
+ self.monsterinfo.attack_state = Defines.AS_SLIDING;
+ else
+ self.monsterinfo.attack_state = Defines.AS_STRAIGHT;
+ }
+
+ return false;
+
+ }
+ };
+ static EntUseAdapter monster_use = new EntUseAdapter()
+ {
+ public void use(edict_t self, edict_t other, edict_t activator)
+ {
+ if (self.enemy != null)
+ return;
+ if (self.health <= 0)
+ return;
+ if ((activator.flags & Defines.FL_NOTARGET) != 0)
+ return;
+ if ((null == activator.client) && 0 == (activator.monsterinfo.aiflags & Defines.AI_GOOD_GUY))
+ return;
+
+ // delay reaction so if the monster is teleported, its sound is still heard
+ self.enemy = activator;
+ GameUtil.FoundTarget(self);
+ }
+ };
+ static boolean enemy_vis;
+ static boolean enemy_infront;
+ static int enemy_range;
+ static float enemy_yaw;
+}