diff --git a/actionlite/g_items.cpp b/actionlite/g_items.cpp index 9b1a11b..d2625d8 100644 --- a/actionlite/g_items.cpp +++ b/actionlite/g_items.cpp @@ -1349,20 +1349,34 @@ static void Use_Compass(edict_t *ent, gitem_t *inv) #define SPEC_RESPAWN_TIME 60 // time before they will get respawned #define SPEC_TECH_TIMEOUT 60 +constexpr item_id_t weap_ids[] = { + IT_WEAPON_MP5, + IT_WEAPON_M4, + IT_WEAPON_M3, + IT_WEAPON_HANDCANNON, + IT_WEAPON_SNIPER, + IT_WEAPON_KNIFE, + }; -void SpecThink(edict_t * spec); - -static edict_t *FindSpecSpawn(void) +static edict_t *FindSpecSpawn() { - edict_t *spot = NULL; - int i = rand() % 16; + return SelectDeathmatchSpawnPoint(false, true, true).spot; +} - while (i--) - spot = G_Find(spot, FOFS(classname), "info_player_deathmatch"); - if (!spot) - spot = G_Find(spot, FOFS(classname), "info_player_deathmatch"); +THINK(SpecThink) (edict_t *special) -> void +{ + edict_t *spot; - return spot; + if ((spot = FindSpecSpawn()) != nullptr) + { + SpawnSpec(special->item, spot); + G_FreeEdict(special); + } + else + { + special->nextthink = level.time + 10_ms; + special->think = SpecThink; + } } static void SpawnSpec(gitem_t * item, edict_t * spot) @@ -1372,15 +1386,14 @@ static void SpawnSpec(gitem_t * item, edict_t * spot) ent = G_Spawn(); ent->classname = item->classname; - ent->typeNum = item->typeNum; ent->item = item; - ent->spawnflags = DROPPED_ITEM; + ent->spawnflags = SPAWNFLAG_ITEM_DROPPED; ent->s.effects = item->world_model_flags; ent->s.renderfx = RF_GLOW; VectorSet(ent->mins, -15, -15, -15); VectorSet(ent->maxs, 15, 15, 15); // zucc dumb hack to make laser look like it is on the ground - if (item->typeNum == LASER_NUM) { + if (item->tag == POWERUP_LASERSIGHT) { VectorSet(ent->mins, -15, -15, -1); VectorSet(ent->maxs, 15, 15, 1); } @@ -1394,52 +1407,18 @@ static void SpawnSpec(gitem_t * item, edict_t * spot) angles[1] = rand() % 360; angles[2] = 0; - AngleVectors(angles, forward, right, NULL); - VectorCopy(spot->s.origin, ent->s.origin); + AngleVectors(angles, forward, right, nullptr); + ent->s.origin = spot->s.origin; ent->s.origin[2] += 16; - VectorCopy(ent->s.origin, ent->old_origin); - VectorScale(forward, 100, ent->velocity); + ent->velocity = forward * 100; ent->velocity[2] = 300; - ent->nextthink = level.framenum + SPEC_RESPAWN_TIME * HZ; + ent->nextthink = level.time + 60_ms; ent->think = SpecThink; gi.linkentity(ent); } -void SpawnSpecs(edict_t * ent) -{ - gitem_t *spec; - edict_t *spot; - int i, itemNum; - - G_FreeEdict(ent); - - // if(item_respawnmode->value) - // return; - - for(i = 0; iitem, spot); - } - - G_FreeEdict(spec); -} static void MakeTouchSpecThink(edict_t * ent) { @@ -1447,31 +1426,26 @@ static void MakeTouchSpecThink(edict_t * ent) ent->touch = Touch_Item; if (allitem->value) { - ent->nextthink = level.framenum + 1 * HZ; + ent->nextthink = level.time + 10_ms; ent->think = G_FreeEdict; return; } if (gameSettings & GS_ROUNDBASED) { - ent->nextthink = level.framenum + 60 * HZ; //FIXME: should this be roundtime left + ent->nextthink = level.time + 60_ms; //FIXME: should this be roundtime left ent->think = G_FreeEdict; return; } if (gameSettings & GS_WEAPONCHOOSE) { - ent->nextthink = level.framenum + 6 * HZ; + ent->nextthink = level.time + 60_ms; ent->think = G_FreeEdict; return; } - if(item_respawnmode->value) { - ent->nextthink = level.framenum + (item_respawn->value*0.5f) * HZ; - ent->think = G_FreeEdict; - } - else { - ent->nextthink = level.framenum + item_respawn->value * HZ; - ent->think = SpecThink; - } + // All else.. + ent->nextthink = level.time + 60_ms; + ent->think = SpecThink; } void Drop_Spec(edict_t * ent, gitem_t * item) @@ -1480,11 +1454,11 @@ void Drop_Spec(edict_t * ent, gitem_t * item) spec = Drop_Item(ent, item); //gi.cprintf(ent, PRINT_HIGH, "Dropping special item.\n"); - spec->nextthink = level.framenum + 1 * HZ; + spec->nextthink = level.time + 10_ms; spec->think = MakeTouchSpecThink; //zucc this and the one below should probably be -- not = 0, if // a server turns on multiple item pickup. - ent->client->inventory[ITEM_INDEX(item)]--; + ent->client->pers.inventory[ITEM_INDEX(item)]--; } void DeadDropSpec(edict_t * ent) @@ -1493,56 +1467,34 @@ void DeadDropSpec(edict_t * ent) edict_t *dropped; int i, itemNum; - for(i = 0; i 0) { - spec = GET_ITEM(itemNum); - dropped = Drop_Item(ent, spec); + if (ent->client->pers.inventory[weap_ids[i]]) + { + dropped = Drop_Item(ent, GetItemByIndex(weap_ids[i])); // hack the velocity to make it bounce random dropped->velocity[0] = (rand() % 600) - 300; dropped->velocity[1] = (rand() % 600) - 300; - dropped->nextthink = level.framenum + 1 * HZ; + dropped->nextthink = level.time + 10_ms; dropped->think = MakeTouchSpecThink; - dropped->owner = NULL; - dropped->spawnflags = DROPPED_PLAYER_ITEM; - ent->client->inventory[ITEM_INDEX(spec)] = 0; + dropped->owner = nullptr; + dropped->spawnflags = SPAWNFLAG_ITEM_DROPPED_PLAYER; + ent->client->pers.inventory[weap_ids[i]] = 0; } } } -// frees the passed edict! -void RespawnSpec(edict_t * ent) -{ - edict_t *spot; - - if ((spot = FindSpecSpawn()) != NULL) - SpawnSpec(ent->item, spot); - G_FreeEdict(ent); -} - -void SetupSpecSpawn(void) -{ - edict_t *ent; - - if (level.specspawn) - return; - - ent = G_Spawn(); - ent->nextthink = level.framenum + 4 * HZ; - ent->think = SpawnSpecs; - level.specspawn = 1; -} - void AddItem(edict_t *ent, gitem_t *item) { - ent->client->inventory[ITEM_INDEX (item)]++; + ent->client->pers.inventory[ITEM_INDEX (item)]++; ent->client->unique_item_total++; - if (item->typeNum == LASER_NUM) + + if (item->tag == POWERUP_LASERSIGHT) { SP_LaserSight(ent, item); //ent->item->use(other, ent->item); } - else if (item->typeNum == BAND_NUM) + else if (item->tag == POWERUP_BANDOLIER) { if (ent->client->max_pistolmags < 4) @@ -1578,12 +1530,14 @@ bool Pickup_Special (edict_t * ent, edict_t * other) return true; } -void Drop_Special (edict_t * ent, gitem_t * item) + + +void Drop_Special (edict_t *ent, gitem_t *item) { int count; ent->client->unique_item_total--; - if (item->typeNum == BAND_NUM && INV_AMMO(ent, BAND_NUM) <= 1) + if (item->tag == POWERUP_BANDOLIER && INV_AMMO(ent, IT_ITEM_BANDOLIER) <= 1) { if (gameSettings & GS_DEATHMATCH) count = 2; @@ -1591,11 +1545,11 @@ void Drop_Special (edict_t * ent, gitem_t * item) count = 1; ent->client->max_pistolmags = count; - if (INV_AMMO(ent, MK23_ANUM) > count) - INV_AMMO(ent, MK23_ANUM) = count; + if (INV_AMMO(ent, IT_AMMO_BULLETS) > count) + INV_AMMO(ent, IT_AMMO_BULLETS) = count; if (!(gameSettings & GS_DEATHMATCH)) { - if(ent->client->pers.chosenWeapon->typeNum == HC_NUM) + if(ent->client->pers.chosenWeapon->id == IT_WEAPON_HANDCANNON) count = 12; else count = 7; @@ -1603,52 +1557,36 @@ void Drop_Special (edict_t * ent, gitem_t * item) count = 14; } ent->client->max_shells = count; - if (INV_AMMO(ent, SHELL_ANUM) > count) - INV_AMMO(ent, SHELL_ANUM) = count; + if (INV_AMMO(ent, IT_AMMO_SHELLS) > count) + INV_AMMO(ent, IT_AMMO_SHELLS) = count; ent->client->max_m4mags = 1; - if (INV_AMMO(ent, M4_ANUM) > 1) - INV_AMMO(ent, M4_ANUM) = 1; + if (INV_AMMO(ent, IT_AMMO_CELLS) > 1) + INV_AMMO(ent, IT_AMMO_CELLS) = 1; ent->client->grenade_max = 2; - if (use_buggy_bandolier->value == 0) { - if ((gameSettings & GS_DEATHMATCH) && INV_AMMO(ent, GRENADE_NUM) > 2) - INV_AMMO(ent, GRENADE_NUM) = 2; - else if (teamplay->value) { - if (ent->client->curr_weap == GRENADE_NUM) - INV_AMMO(ent, GRENADE_NUM) = 1; - else - INV_AMMO(ent, GRENADE_NUM) = 0; - } - } else { - if (INV_AMMO(ent, GRENADE_NUM) > 2) - INV_AMMO(ent, GRENADE_NUM) = 2; + if (INV_AMMO(ent, IT_WEAPON_GRENADES) > 2) + INV_AMMO(ent, IT_WEAPON_GRENADES) = 2; } if (gameSettings & GS_DEATHMATCH) count = 2; else count = 1; ent->client->max_mp5mags = count; - if (INV_AMMO(ent, MP5_ANUM) > count) - INV_AMMO(ent, MP5_ANUM) = count; + if (INV_AMMO(ent, IT_AMMO_ROCKETS) > count) + INV_AMMO(ent, IT_AMMO_ROCKETS) = count; ent->client->knife_max = 10; - if (INV_AMMO(ent, KNIFE_NUM) > 10) - INV_AMMO(ent, KNIFE_NUM) = 10; + if (INV_AMMO(ent, IT_WEAPON_KNIFE) > 10) + INV_AMMO(ent, IT_WEAPON_KNIFE) = 10; if (gameSettings & GS_DEATHMATCH) count = 20; else count = 10; ent->client->max_sniper_rnds = count; - if (INV_AMMO(ent, SNIPER_ANUM) > count) - INV_AMMO(ent, SNIPER_ANUM) = count; - - if (ent->client->unique_weapon_total > unique_weapons->value && !allweapon->value) - { - DropExtraSpecial (ent); - gi.cprintf (ent, PRINT_HIGH, "One of your guns is dropped with the bandolier.\n"); - } + if (INV_AMMO(ent, IT_AMMO_SLUGS) > count) + INV_AMMO(ent, IT_AMMO_SLUGS) = count; } Drop_Spec(ent, item); ValidateSelectedItem(ent); @@ -2215,7 +2153,7 @@ model="models/items/ammo/rockets/medium/tris.md2" /*QUAKED item_helmet (.3 .3 1) (-16 -16 -16) (16 16 16) */ { - /* id */ IT_ITEM_LASERSIGHT, + /* id */ IT_ITEM_HELM, /* classname */ "item_helmet", /* pickup */ Pickup_Special, /* use */ nullptr, diff --git a/actionlite/g_local.h b/actionlite/g_local.h index c3ce045..5b4534b 100644 --- a/actionlite/g_local.h +++ b/actionlite/g_local.h @@ -1861,6 +1861,52 @@ extern gitem_t itemlist[IT_TOTAL]; // Action Add //====================================================================== +#define IS_ALIVE(ent) ((ent)->solid != SOLID_NOT && (ent)->deadflag) + +#define GS_DEATHMATCH 1 +#define GS_TEAMPLAY 2 +#define GS_MATCHMODE 4 +#define GS_ROUNDBASED 8 +#define GS_WEAPONCHOOSE 16 + +// sniper modes +#define SNIPER_1X 0 +#define SNIPER_2X 1 +#define SNIPER_4X 2 +#define SNIPER_6X 3 +#define SNIPER_MODE_MAX 4 + +//TempFile sniper zoom moved to constants +#define SNIPER_FOV1 90 +#define SNIPER_FOV2 45 +#define SNIPER_FOV4 20 +#define SNIPER_FOV6 10 + +#define GRENADE_IDLE_FIRST 40 +#define GRENADE_IDLE_LAST 69 +#define GRENADE_THROW_FIRST 4 +#define GRENADE_THROW_LAST 9 // throw it on frame 8? +// Igor's back in Time to hard grenades :-) +#define GRENADE_DAMRAD_CLASSIC 170 +#define GRENADE_DAMRAD 250 + +#define SPEC_WEAPON_RESPAWN 1 +#define BANDAGE_TIME 27 // 10 = 1 second +#define ENHANCED_BANDAGE_TIME 10 +#define BLEED_TIME 10 // 10 = 1 second is time for losing 1 health at slowest bleed rate + + +int32_t gameSettings; // Round based, deathmatch, etc? + +extern cvar_t *allitem; +extern cvar_t *allweapon; +extern cvar_t *unique_items; +extern cvar_t *unique_weapons; +extern cvar_t *allow_hoarding; +extern cvar_t *item_respawn; +extern cvar_t *weapon_respawn; +extern cvar_t *ammo_respawn; + void LaserSightThink (edict_t * self); void SP_LaserSight (edict_t * self, gitem_t * item); void Cmd_Reload_f (edict_t * ent); @@ -1903,7 +1949,7 @@ void Compass_Update(edict_t *ent, bool first); // ACTION #define ITEM_INDEX(x) ((x)-itemlist) -#define INV_AMMO(ent, num) ((ent)->client->inventory[items[(num)].index]) +#define INV_AMMO(ent, num) ((ent)->client->pers.inventory[items[(num)].index]) #define GET_ITEM(num) (&itemlist[items[(num)].index]) // @@ -2665,6 +2711,22 @@ struct client_persistant_t int32_t lives; // player lives left (1 = no respawns remaining) uint8_t n64_crouch_warn_times; gtime_t n64_crouch_warning; + + // Action Add + + gitem_t *chosenItem; // item for teamplay + gitem_t *chosenWeapon; // weapon for teamplay + int32_t mk23_mode; // firing mode, semi or auto + int32_t mp5_mode; + int32_t m4_mode; + int32_t knife_mode; + int32_t grenade_mode; + int32_t hc_mode; + int32_t id; // id command on or off + int32_t irvision; // ir on or off (only matters if player has ir device, currently bandolier) + + + // Action Add End }; // client data that stays across deathmatch respawns @@ -2898,6 +2960,36 @@ struct gclient_t height_fog_t heightfog; gtime_t last_attacker_time; + + // Action Add + int32_t unique_item_total; + int32_t unique_weapon_total; + + int inventory[MAX_ITEMS]; + // ammo capacities + int32_t max_pistolmags; + int32_t max_shells; + int32_t max_mp5mags; + int32_t max_m4mags; + int32_t max_sniper_rnds; + int32_t mk23_max; + int32_t mk23_rds; + int32_t dual_max; + int32_t dual_rds; + int32_t shot_max; + int32_t shot_rds; + int32_t sniper_max; + int32_t sniper_rds; + int32_t mp5_max; + int32_t mp5_rds; + int32_t m4_max; + int32_t m4_rds; + int32_t cannon_max; + int32_t cannon_rds; + int32_t knife_max; + int32_t grenade_max; + + // Action Add End }; // ========================================== diff --git a/actionlite/g_main.cpp b/actionlite/g_main.cpp index f794435..2956c65 100644 --- a/actionlite/g_main.cpp +++ b/actionlite/g_main.cpp @@ -137,6 +137,24 @@ cvar_t *ai_model_scale; cvar_t *ai_allow_dm_spawn; cvar_t *ai_movement_disabled; +//====================================================================== +// Action Add +//====================================================================== + +cvar_t *allitem; +cvar_t *allweapon; +cvar_t *unique_items; +cvar_t *unique_weapons; +cvar_t *allow_hoarding; +cvar_t *item_respawn; +cvar_t *weapon_respawn; +cvar_t *ammo_respawn; + +//====================================================================== +// Action Add End +//====================================================================== + + static cvar_t *g_frames_per_frame; void SpawnEntities(const char *mapname, const char *entities, const char *spawnpoint); @@ -352,6 +370,23 @@ void InitGame() g_map_list_shuffle = gi.cvar("g_map_list_shuffle", "0", CVAR_NOFLAGS); g_lag_compensation = gi.cvar("g_lag_compensation", "1", CVAR_NOFLAGS); +//====================================================================== +// Action Add +//====================================================================== + + allitem = gi.cvar("allitem", "0", CVAR_NOFLAGS); + allweapon = gi.cvar("allweapon", "0", CVAR_NOFLAGS); + unique_items = gi.cvar("unique_items", "1", CVAR_NOFLAGS); + unique_weapons = gi.cvar("unique_weapons", "1", CVAR_NOFLAGS); + allow_hoarding = gi.cvar("allow_hoarding", "0", CVAR_NOFLAGS); + item_respawn = gi.cvar("item_respawn", "59", CVAR_NOFLAGS); + weapon_respawn = gi.cvar("weapon_respawn", "74", CVAR_NOFLAGS); + ammo_respawn = gi.cvar("ammo_respawn", "30", CVAR_NOFLAGS); + +//====================================================================== +// Action Add +//====================================================================== + // items InitItems();