diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 01c24d9d4..2288e859b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ D1X-Rebirth Changelog 20110114 -------- main/credits.c, main/menu.c, main/net_udp.c, main/scores.c: Fix compile errors introduced when merging +main/collide.c, main/fireball.c, main/gamesave.c, main/gameseq.c, main/gameseq.h, main/laser.c, main/multi.c, main/multi.h, main/multibot.c, main/net_ipx.c, main/net_udp.c, main/object.c, main/powerup.c, main/powerup.h, main/weapon.c, main/weapon.h: Removed D1X implementation of multiplayer powerup capping and added D2X code to replace this (UDP-only); Added a bunch of D2X code for general and multiplayer powerup dropping to make codes more consistent to each other; Removed MULTI_PROTO_D1X_VER and MULTI_PROTO_D1X_MINOR defines since they are not needed anymore 20110113 -------- diff --git a/main/collide.c b/main/collide.c index bdf5c10bb..de7e144c3 100644 --- a/main/collide.c +++ b/main/collide.c @@ -1075,99 +1075,55 @@ void collide_player_and_player( object * player1, object * player2, vms_vector * return; } -// drop powerups in pow_count around object obj. -// special behavior: -// - POW_MISSILE_1 and POW_HOMING_AMMO_1 are split into -// POW_MISSILE_1/4 and POW_HOMING_AMMO_1/4 respectivily. -// - for single player: -// when dropping POW_VULCAN_WEAPON it gets all ammo (POW_VULCAN_AMMO), -// and no vulcan ammo is dropped. -// for multi player: -// when dropping POW_VULCAN_WEAPON it gets VULCAN_WEAPON_AMMO_AMOUNT -// ammo, and that's subtracted from the to be dropped ammo packages. -// - when dropping vulcan ammo w/o cannon, ammo is limited to 200 max -void drop_pow_count(object *obj, int *pow_count) +int maybe_drop_primary_weapon_egg(object *playerobj, int weapon_index) { - int i, j; - int count; - int objnum; - int powerup_in_level[MAX_POWERUP_TYPES]; + int weapon_flag = HAS_FLAG(weapon_index); + int powerup_num; - pow_count_level(powerup_in_level); + powerup_num = Primary_weapon_to_powerup[weapon_index]; - for (j = 0; j < NUM_PLAYER_DROP_POWERUPS; j++) - { - count = pow_count[(i = player_drop_powerups[j])]; - - // limit powerups in D1X network games -#ifdef USE_IPX - if ((Game_mode & GM_NETWORK) && - (Netgame.protocol.ipx.protocol_version == MULTI_PROTO_D1X_VER)) - { - if (multi_allow_powerup_mask[i]) - { // only check 'important' powerups (no shield,energy,conc) - int pow_max = max(powerup_start_level[i] - powerup_in_level[i], 0); - -//-killed- #ifdef NETWORK - while (count > pow_max) - { - // create dummy Net_create_objnums entries to keep objnums in sync - if (Net_create_loc >= MAX_NET_CREATE_OBJECTS) - { - return; - } - Net_create_objnums[Net_create_loc++] = -1; - count--; - } -//-killed- #else -//-killed- if (count > pow_max) count = pow_max; -//-killed- #endif - } - } -#endif - - if (count > 0) - switch (i) - { - case POW_MISSILE_1: - case POW_HOMING_AMMO_1: - call_object_create_egg(obj, count / 4, OBJ_POWERUP, i + 1); - call_object_create_egg(obj, count % 4, OBJ_POWERUP, i); - break; - case POW_VULCAN_WEAPON: - if ((objnum = call_object_create_egg(obj, count, OBJ_POWERUP, POW_VULCAN_WEAPON)) != -1) - { - //added/changed on 9/5/98 by adb (from Matthew Mueller) to drop ammo in multi even with cannon - if (Game_mode & GM_MULTI) { - Objects[objnum].ctype.powerup_info.count = VULCAN_WEAPON_AMMO_AMOUNT; - } else - Objects[objnum].ctype.powerup_info.count = pow_count[POW_VULCAN_AMMO]; - //end change - adb (from Matthew Mueller) - } - break; - case POW_VULCAN_AMMO: - //changed by adb on 980905 to drop ammo in multi even with cannon - if (pow_count[POW_VULCAN_WEAPON]) - count -= VULCAN_WEAPON_AMMO_AMOUNT; - if (count > 0 && (pow_count[POW_VULCAN_WEAPON] == 0 || (Game_mode & GM_MULTI))) { - if (count > 200) { - count = 200; - } - call_object_create_egg(obj, (count + VULCAN_AMMO_AMOUNT - 1) / VULCAN_AMMO_AMOUNT, OBJ_POWERUP, POW_VULCAN_AMMO); - } - //end changes by adb - break; - default: - call_object_create_egg(obj, count, OBJ_POWERUP, i); - } - } + if (Players[playerobj->id].primary_weapon_flags & weapon_flag) + return call_object_create_egg(playerobj, 1, OBJ_POWERUP, powerup_num); + else + return -1; } -void drop_player_eggs(object *player) +void maybe_drop_secondary_weapon_egg(object *playerobj, int weapon_index, int count) { - if ((player->type == OBJ_PLAYER) || (player->type == OBJ_GHOST)) { - int pnum = player->id; - int pow_count[MAX_POWERUP_TYPES]; + int weapon_flag = HAS_FLAG(weapon_index); + int powerup_num; + + powerup_num = Secondary_weapon_to_powerup[weapon_index]; + + if (Players[playerobj->id].secondary_weapon_flags & weapon_flag) { + int i, max_count; + + max_count = min(count, 3); + for (i=0; iid].secondary_ammo[missile_index]; + powerup_id = Secondary_weapon_to_powerup[missile_index]; + + if (num_missiles > 10) + num_missiles = 10; + + call_object_create_egg(playerobj, num_missiles/4, OBJ_POWERUP, powerup_id+1); + call_object_create_egg(playerobj, num_missiles%4, OBJ_POWERUP, powerup_id); +} + +void drop_player_eggs(object *playerobj) +{ + if ((playerobj->type == OBJ_PLAYER) || (playerobj->type == OBJ_GHOST)) { + int pnum = playerobj->id; + int objnum; + int vulcan_ammo=0; // Seed the random number generator so in net play the eggs will always // drop the same way @@ -1179,9 +1135,60 @@ void drop_player_eggs(object *player) } #endif - player_to_pow_count(&Players[pnum], pow_count); - clip_player_pow_count(pow_count); - drop_pow_count(player, pow_count); + // If the player dies and he has powerful lasers, create the powerups here. + + if (Players[pnum].laser_level >= 1) + call_object_create_egg(playerobj, Players[pnum].laser_level, OBJ_POWERUP, POW_LASER); // Note: laser_level = 0 for laser level 1. + + // Drop quad laser if appropos + if (Players[pnum].flags & PLAYER_FLAGS_QUAD_LASERS) + call_object_create_egg(playerobj, 1, OBJ_POWERUP, POW_QUAD_FIRE); + + if (Players[pnum].flags & PLAYER_FLAGS_CLOAKED) + call_object_create_egg(playerobj, 1, OBJ_POWERUP, POW_CLOAK); + + //Drop the vulcan, gauss, and ammo + vulcan_ammo = Players[pnum].primary_ammo[VULCAN_INDEX]; + if (vulcan_ammo < VULCAN_AMMO_AMOUNT) + vulcan_ammo = VULCAN_AMMO_AMOUNT; //make sure gun has at least as much as a powerup + objnum = maybe_drop_primary_weapon_egg(playerobj, VULCAN_INDEX); + if (objnum!=-1) + Objects[objnum].ctype.powerup_info.count = vulcan_ammo; + + // Drop the rest of the primary weapons + maybe_drop_primary_weapon_egg(playerobj, SPREADFIRE_INDEX); + maybe_drop_primary_weapon_egg(playerobj, PLASMA_INDEX); + maybe_drop_primary_weapon_egg(playerobj, FUSION_INDEX); + + // Drop the secondary weapons + // Note, proximity weapon only comes in packets of 4. So drop n/2, but a max of 3 (handled inside maybe_drop..) Make sense? + + maybe_drop_secondary_weapon_egg(playerobj, PROXIMITY_INDEX, (Players[playerobj->id].secondary_ammo[PROXIMITY_INDEX])/4); + + maybe_drop_secondary_weapon_egg(playerobj, SMART_INDEX, Players[playerobj->id].secondary_ammo[SMART_INDEX]); + maybe_drop_secondary_weapon_egg(playerobj, MEGA_INDEX, Players[playerobj->id].secondary_ammo[MEGA_INDEX]); + + // Drop the player's missiles in packs of 1 and/or 4 + drop_missile_1_or_4(playerobj,HOMING_INDEX); + drop_missile_1_or_4(playerobj,CONCUSSION_INDEX); + + // If player has vulcan ammo, but no vulcan cannon, drop the ammo. + if (!(Players[playerobj->id].primary_weapon_flags & HAS_VULCAN_FLAG)) { + int amount = Players[playerobj->id].primary_ammo[VULCAN_INDEX]; + if (amount > 200) { + amount = 200; + } + while (amount > 0) { + call_object_create_egg(playerobj, 1, OBJ_POWERUP, POW_VULCAN_AMMO); + amount -= VULCAN_AMMO_AMOUNT; + } + } + + // Always drop a shield and energy powerup. + if (Game_mode & GM_MULTI) { + call_object_create_egg(playerobj, 1, OBJ_POWERUP, POW_SHIELD_BOOST); + call_object_create_egg(playerobj, 1, OBJ_POWERUP, POW_ENERGY); + } } } diff --git a/main/fireball.c b/main/fireball.c index ad67742c9..a833df057 100644 --- a/main/fireball.c +++ b/main/fireball.c @@ -433,6 +433,7 @@ int choose_drop_segment(void) } +extern char PowerupsInMine[],MaxPowerupsAllowed[]; // ------------------------------------------------------------------------------------------------------ // Drop cloak powerup if in a network game. void maybe_drop_net_powerup(int powerup_type) @@ -441,8 +442,13 @@ void maybe_drop_net_powerup(int powerup_type) int segnum, objnum; vms_vector new_pos; - if (Control_center_destroyed || Endlevel_sequence || - !may_create_powerup(powerup_type)) + if (Game_mode & GM_NETWORK) + { + if (PowerupsInMine[powerup_type]>=MaxPowerupsAllowed[powerup_type]) + return; + } + + if (Control_center_destroyed || Endlevel_sequence) return; segnum = choose_drop_segment(); @@ -964,8 +970,7 @@ void do_explosion_sequence(object *obj) // If dropping a weapon that the player has, drop energy instead, unless it's vulcan, in which case drop vulcan ammo. if (del_obj->contains_type == OBJ_POWERUP) maybe_replace_powerup_with_energy(del_obj); - if (object_create_egg(del_obj) >= 0) - pow_add_random(del_obj); + object_create_egg(del_obj); } else if ((del_obj->type == OBJ_ROBOT) && !(Game_mode & GM_MULTI)) { // Multiplayer handled outside this code!! robot_info *robptr = &Robot_info[del_obj->id]; if (robptr->contains_count) { @@ -974,8 +979,7 @@ void do_explosion_sequence(object *obj) del_obj->contains_type = robptr->contains_type; del_obj->contains_id = robptr->contains_id; maybe_replace_powerup_with_energy(del_obj); - if (object_create_egg(del_obj) >= 0) - pow_add_random(del_obj); + object_create_egg(del_obj); } } } diff --git a/main/gamesave.c b/main/gamesave.c index 54e99100b..95c2cc011 100644 --- a/main/gamesave.c +++ b/main/gamesave.c @@ -277,6 +277,20 @@ void verify_object( object * obj ) { obj->control_type = CT_POWERUP; obj->size = Powerup_info[obj->id].size; + + if (Game_mode & GM_NETWORK) + { + if (multi_powerup_is_4pack(obj->id)) + { + PowerupsInMine[obj->id-1]+=4; + MaxPowerupsAllowed[obj->id-1]+=4; + } + else + { + PowerupsInMine[obj->id]++; + MaxPowerupsAllowed[obj->id]++; + } + } } if ( obj->type == OBJ_WEAPON ) { diff --git a/main/gameseq.c b/main/gameseq.c index 6a06479ca..821ac081e 100644 --- a/main/gameseq.c +++ b/main/gameseq.c @@ -1243,8 +1243,6 @@ void StartNewLevelSub(int level_num, int page_in_textures) gameseq_remove_unused_players(); - count_powerup_start_level(); - Game_suspended = 0; Control_center_destroyed = 0; @@ -1289,6 +1287,24 @@ void StartNewLevelSub(int level_num, int page_in_textures) game(); } +#ifdef NETWORK +extern char PowerupsInMine[MAX_POWERUP_TYPES], MaxPowerupsAllowed[MAX_POWERUP_TYPES]; +#endif +void bash_to_shield (int i,char *s) +{ +#ifdef NETWORK + int type=Objects[i].id; +#endif + +#ifdef NETWORK + PowerupsInMine[type]=MaxPowerupsAllowed[type]=0; +#endif + + Objects[i].id = POW_SHIELD_BOOST; + Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; + Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; +} + //called when the player is starting a new level for normal game model void StartNewLevel(int level_num) { diff --git a/main/gameseq.h b/main/gameseq.h index 95bbacfb1..d3950cc04 100644 --- a/main/gameseq.h +++ b/main/gameseq.h @@ -116,4 +116,6 @@ extern void DoEndLevelScoreGlitz(int network); extern int MaxNumNetPlayers; extern int NumNetPlayerPositions; +void bash_to_shield(int, char *); + #endif /* _GAMESEQ_H */ diff --git a/main/laser.c b/main/laser.c index e1911552b..b326810bd 100644 --- a/main/laser.c +++ b/main/laser.c @@ -1457,14 +1457,12 @@ void create_smart_children(object *objp) #define MEGA_GUN 7 -int Missile_gun=0; +int Missile_gun=0, Proximity_dropped = 0; // ------------------------------------------------------------------------------------------- //changed on 9/16/98 by adb to distinguish between drop bomb and secondary fire void do_missile_firing(int drop_bomb) { - static int proximity = 0; - int weapon = (drop_bomb) ? PROXIMITY_INDEX : Secondary_weapon; Assert(weapon < MAX_SECONDARY_WEAPONS); @@ -1488,10 +1486,10 @@ void do_missile_firing(int drop_bomb) break; case PROXIMITY_INDEX: - proximity ++; - if (proximity == 4) + Proximity_dropped ++; + if (Proximity_dropped == 4) { - proximity = 0; + Proximity_dropped = 0; #ifdef NETWORK maybe_drop_net_powerup(POW_PROXIMITY_WEAPON); #endif diff --git a/main/multi.c b/main/multi.c index 8a0d7aee8..88e991b58 100644 --- a/main/multi.c +++ b/main/multi.c @@ -74,8 +74,10 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #define vm_angvec_zero(v) (v)->p=(v)->b=(v)->h=0 void reset_player_object(void); // In object.c but not in object.h -void drop_player_eggs(object *player); // from collide.c +void drop_player_eggs(object *playerobj); // from collide.c void StartLevel(void); // From gameseq.c +void multi_powcap_cap_objects(); +void multi_powcap_adjust_remote_cap(int pnum); // // Global variables @@ -126,6 +128,9 @@ int Network_send_object_mode = 0; // What type of objects are we sending, static int Network_send_objnum = -1; // What object are we sending next? int Network_rejoined = 0; // Did WE rejoin this game? int Network_new_game = 0; // Is this the first level of a new game? +int Network_sending_extras=0; +int VerifyPlayerJoined=-1; // Player (num) to enter game before any ingame/extra stuff is being sent +int Player_joining_extras=-1; // This is so we know who to send 'latecomer' packets to. int Network_player_added = 0; // Is this a new player or a returning player? //added 02/26/99 Matt Mueller - reactor kill stats @@ -133,9 +138,6 @@ short reactor_kills[MAX_NUM_NET_PLAYERS]; int reactor_kills_total; //end addition -MM -uint multi_allow_powerup; -uint multi_got_pow_count; - ushort my_segments_checksum = 0; netgame_info Netgame; @@ -146,6 +148,8 @@ bitmap_index multi_player_textures[MAX_NUM_NET_PLAYERS][N_PLAYER_SHIP_TEXTURES]; char RefuseThisPlayer=0,WaitForRefuseAnswer=0,RefuseTeam,RefusePlayerName[12]; fix64 RefuseTimeLimit=0; +char PowerupsInMine[MAX_POWERUP_TYPES],MaxPowerupsAllowed[MAX_POWERUP_TYPES]; + int message_length[MULTI_MAX_TYPE+1] = { 25, // POSITION 3, // REAPPEAR @@ -184,8 +188,7 @@ int message_length[MULTI_MAX_TYPE+1] = { 2+4, //RESTORE_GAME (ubyte slot, uint id) // obsolete -1, // MULTI_REQ_PLAYER - NEVER USED -1, // MULTI_SEND_PLAYER - NEVER USED - 19, // PLAYER_POWERUP_COUNT - 19, // START_POWERUP_COUNT + MAX_POWERUP_TYPES+1, // MULTI_POWCAP_UPDATE }; void multi_reset_player_object(object *objp); @@ -371,6 +374,12 @@ multi_endlevel_score(void) // Reset keys Players[i].flags &= ~(PLAYER_FLAGS_BLUE_KEY | PLAYER_FLAGS_RED_KEY | PLAYER_FLAGS_GOLD_KEY); } + + for (i=0;iphys_info.velocity = *(vms_vector *)(buf+16); // 12 bytes @@ -1611,6 +1588,23 @@ multi_do_remobj(char *buf) Network_send_objnum = -1; } + if (Objects[local_objnum].type==OBJ_POWERUP) + if (Game_mode & GM_NETWORK) + { + if (multi_powerup_is_4pack (Objects[local_objnum].id)) + { + if (PowerupsInMine[Objects[local_objnum].id-1]-4<0) + PowerupsInMine[Objects[local_objnum].id-1]=0; + else + PowerupsInMine[Objects[local_objnum].id-1]-=4; + } + else + { + if (PowerupsInMine[Objects[local_objnum].id]>0) + PowerupsInMine[Objects[local_objnum].id]--; + } + } + Objects[local_objnum].flags |= OF_SHOULD_BE_DEAD; // quick and painless } @@ -1790,9 +1784,6 @@ multi_do_create_powerup(char *buf) new_pos.z = (fix)SWAPINT((int)new_pos.z); #endif - if (!may_create_powerup(powerup_type)) - return; - Net_create_loc = 0; my_objnum = call_object_create_egg(&Objects[Players[pnum].objnum], 1, OBJ_POWERUP, powerup_type); @@ -1814,6 +1805,14 @@ multi_do_create_powerup(char *buf) map_objnum_local_to_remote(my_objnum, objnum, pnum); object_create_explosion(segnum, &new_pos, i2f(5), VCLIP_POWERUP_DISAPPEARANCE); + + if (Game_mode & GM_NETWORK) + { + if (multi_powerup_is_4pack((int)powerup_type)) + PowerupsInMine[(int)(powerup_type-1)]+=4; + else + PowerupsInMine[(int)powerup_type]++; + } } void @@ -2050,9 +2049,8 @@ multi_process_data(char *buf, int len) if (!Endlevel_sequence) multi_do_create_robot_powerups(buf); break; case MULTI_HOSTAGE_DOOR: if (!Endlevel_sequence) multi_do_hostage_door_status(buf); break; - case MULTI_PLAYER_POWERUP_COUNT: - case MULTI_START_POWERUP_COUNT: - if (!Endlevel_sequence) multi_do_powerup_count(buf); break; + case MULTI_POWCAP_UPDATE: + if (!Endlevel_sequence) multi_do_powcap_update(buf); break; default: Int3(); } @@ -2163,42 +2161,6 @@ multi_send_endlevel_start(int secret) } } -void -multi_send_powerup_count(char type, int *pow_count) -{ - int i, pow; - int count = 0; - - multibuf[count++] = type; - multibuf[count++] = Player_num; - for (i = 0; i < NUM_PLAYER_DROP_POWERUPS; i++) - { - pow = player_drop_powerups[i]; - if (pow == POW_VULCAN_AMMO) - { - *((short *)&multibuf[count]) = pow_count[pow]; count += 2; - } - else - multibuf[count++] = pow_count[pow]; - } - multi_send_data(multibuf, count, 1); -} - -void -multi_send_player_powerup_count() -{ - int pow_count[MAX_POWERUP_TYPES]; - - player_to_pow_count(&Players[Player_num], pow_count); - multi_send_powerup_count(MULTI_PLAYER_POWERUP_COUNT, pow_count); -} - -void -multi_send_start_powerup_count() -{ - multi_send_powerup_count(MULTI_START_POWERUP_COUNT, powerup_start_level); -} - void multi_send_player_explode(char type) { @@ -2262,6 +2224,152 @@ multi_send_player_explode(char type) multi_strip_robots(Player_num); } +extern ubyte Secondary_weapon_to_powerup[], Primary_weapon_to_powerup[]; +extern int Proximity_dropped; + +/* + * Powerup capping: Keep track of how many powerups are in level and kill these which would exceed initial limit. + * NOTE: Code from D2 - never been in D1, so disable in IPX + */ + +// Count the initial amount of Powerups in the level +void multi_powcap_count_powerups_in_mine(void) +{ + int i; + + for (i=0;i=MaxPowerupsAllowed[(int)type]) + if(Players[Player_num].primary_weapon_flags & (1 << index)) + { + con_printf(CON_NORMAL,"PIM=%d MPA=%d\n",PowerupsInMine[(int)type],MaxPowerupsAllowed[(int)type]); + con_printf(CON_NORMAL,"Killing a primary cuz there's too many! (%d)\n",type); + Players[Player_num].primary_weapon_flags&=(~(1 << index)); + } + } + + + Players[Player_num].secondary_ammo[2]/=4; + + for (index=0;indexMaxPowerupsAllowed[(int)type]) + { + if (MaxPowerupsAllowed[(int)type]-PowerupsInMine[(int)type]<0) + Players[Player_num].secondary_ammo[index]=0; + else + Players[Player_num].secondary_ammo[index]=(MaxPowerupsAllowed[(int)type]-PowerupsInMine[(int)type]); + con_printf(CON_NORMAL,"Hey! I killed secondary type %d because PIM=%d MPA=%d\n",type,PowerupsInMine[(int)type],MaxPowerupsAllowed[(int)type]); + } + } + + Players[Player_num].secondary_ammo[2]*=4; + + if (Players[Player_num].flags & PLAYER_FLAGS_QUAD_LASERS) + if (PowerupsInMine[POW_QUAD_FIRE]+1 > MaxPowerupsAllowed[POW_QUAD_FIRE]) + Players[Player_num].flags&=(~PLAYER_FLAGS_QUAD_LASERS); + + if (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED) + if (PowerupsInMine[POW_CLOAK]+1 > MaxPowerupsAllowed[POW_CLOAK]) + Players[Player_num].flags&=(~PLAYER_FLAGS_CLOAKED); +} + +// Adds players inventory to multi cap +void multi_powcap_adjust_cap_for_player(int pnum) +{ + char type; + + int index; + + if (!(Game_mode & GM_NETWORK)) + return; + + for (index=0;index0) + PowerupsInMine[Objects[objnum].id]--; + } + } + multibuf[0] = (char)MULTI_REMOVE_OBJECT; remote_objnum = objnum_local_to_remote((short)objnum, &obj_owner); @@ -2479,6 +2603,14 @@ multi_send_create_powerup(int powerup_type, int segnum, int objnum, vms_vector * multi_send_position(Players[Player_num].objnum); + if (Game_mode & GM_NETWORK) + { + if (multi_powerup_is_4pack(powerup_type)) + PowerupsInMine[powerup_type-1]+=4; + else + PowerupsInMine[powerup_type]++; + } + multibuf[count] = MULTI_CREATE_POWERUP; count += 1; multibuf[count] = Player_num; count += 1; multibuf[count] = powerup_type; count += 1; @@ -2657,6 +2789,12 @@ multi_prep_level(void) multi_set_robot_ai(); // Set all Robot AI to types we can cope with } + if (Game_mode & GM_NETWORK) + { + multi_powcap_adjust_cap_for_player(Player_num); + multi_send_powcap_update(); + } + inv_count = 0; cloak_count = 0; for (i=0; i<=Highest_object_index; i++) @@ -2681,31 +2819,33 @@ multi_prep_level(void) if (Objects[i].type == OBJ_POWERUP) { - if (Objects[i].id == POW_EXTRA_LIFE) + if (Objects[i].id == POW_EXTRA_LIFE) { - Objects[i].id = POW_INVULNERABILITY; - Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; - Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; + if (!(Netgame.AllowedItems & NETFLAG_DOINVUL)) + { + Objects[i].id = POW_SHIELD_BOOST; + Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; + Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; + } + else + { + Objects[i].id = POW_INVULNERABILITY; + Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; + Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; + } + } - if ((multi_allow_powerup & multi_allow_powerup_mask[Objects[i].id]) != multi_allow_powerup_mask[Objects[i].id]) { - Objects[i].id = POW_SHIELD_BOOST; - Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; - Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; - } - - if (Game_mode & GM_MULTI_COOP) - continue; - - if ((Objects[i].id >= POW_KEY_BLUE) && (Objects[i].id <= POW_KEY_GOLD)) - { - Objects[i].id = POW_SHIELD_BOOST; - Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; - Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; - } + if (!(Game_mode & GM_MULTI_COOP)) + if ((Objects[i].id >= POW_KEY_BLUE) && (Objects[i].id <= POW_KEY_GOLD)) + { + Objects[i].id = POW_SHIELD_BOOST; + Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; + Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; + } if (Objects[i].id == POW_INVULNERABILITY) { - if (inv_count >= 3) { + if (inv_count >= 3 || (!(Netgame.AllowedItems & NETFLAG_DOINVUL))) { Objects[i].id = POW_SHIELD_BOOST; Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; @@ -2714,13 +2854,38 @@ multi_prep_level(void) } if (Objects[i].id == POW_CLOAK) { - if (cloak_count >= 3) { + if (cloak_count >= 3 || (!(Netgame.AllowedItems & NETFLAG_DOCLOAK))) { Objects[i].id = POW_SHIELD_BOOST; Objects[i].rtype.vclip_info.vclip_num = Powerup_info[Objects[i].id].vclip_num; Objects[i].rtype.vclip_info.frametime = Vclip[Objects[i].rtype.vclip_info.vclip_num].frame_time; } else cloak_count++; } + + if (Objects[i].id == POW_FUSION_WEAPON && !(Netgame.AllowedItems & NETFLAG_DOFUSION)) + bash_to_shield (i,"fusion"); + if (Objects[i].id == POW_MEGA_WEAPON && !(Netgame.AllowedItems & NETFLAG_DOMEGA)) + bash_to_shield (i,"mega"); + if (Objects[i].id == POW_SMARTBOMB_WEAPON && !(Netgame.AllowedItems & NETFLAG_DOSMART)) + bash_to_shield (i,"smartmissile"); + if (Objects[i].id == POW_VULCAN_WEAPON && !(Netgame.AllowedItems & NETFLAG_DOVULCAN)) + bash_to_shield (i,"vulcan"); + if (Objects[i].id == POW_PLASMA_WEAPON && !(Netgame.AllowedItems & NETFLAG_DOPLASMA)) + bash_to_shield (i,"plasma"); + if (Objects[i].id == POW_PROXIMITY_WEAPON && !(Netgame.AllowedItems & NETFLAG_DOPROXIM)) + bash_to_shield (i,"proximity"); + if (Objects[i].id==POW_VULCAN_AMMO && (!(Netgame.AllowedItems & NETFLAG_DOVULCAN))) + bash_to_shield(i,"vulcan ammo"); + if (Objects[i].id == POW_SPREADFIRE_WEAPON && !(Netgame.AllowedItems & NETFLAG_DOSPREAD)) + bash_to_shield (i,"spread"); + if (Objects[i].id == POW_LASER && !(Netgame.AllowedItems & NETFLAG_DOLASER)) + bash_to_shield (i,"Laser powerup"); + if (Objects[i].id == POW_HOMING_AMMO_1 && !(Netgame.AllowedItems & NETFLAG_DOHOMING)) + bash_to_shield (i,"Homing"); + if (Objects[i].id == POW_HOMING_AMMO_4 && !(Netgame.AllowedItems & NETFLAG_DOHOMING)) + bash_to_shield (i,"Homing"); + if (Objects[i].id == POW_QUAD_FIRE && !(Netgame.AllowedItems & NETFLAG_DOQUAD)) + bash_to_shield (i,"Quad Lasers"); } } @@ -2731,16 +2896,6 @@ multi_prep_level(void) ConsoleObject->control_type = CT_FLYING; reset_player_object(); - - multi_got_pow_count = 0; - -#ifdef USE_IPX - // send player powerups (assumes sync already send) - if ((Game_mode & GM_NETWORK) && - Netgame.protocol.ipx.protocol_version == MULTI_PROTO_D1X_VER && - !Network_rejoined) - multi_send_player_powerup_count(); -#endif } int multi_level_sync(void) @@ -2866,6 +3021,45 @@ void change_playernum_to( int new_Player_num ) Player_num = new_Player_num; } +void multi_send_powcap_update () +{ + int i; + + if (multi_protocol == MULTI_PROTO_IPX) + return; + + multibuf[0]=MULTI_POWCAP_UPDATE; + for (i=0;iMaxPowerupsAllowed[i]) + MaxPowerupsAllowed[i]=buf[i+1]; +} + +#define POWERUPADJUSTS 2 +int PowerupAdjustMapping[]={11,19}; + +int multi_powerup_is_4pack (int id) +{ + int i; + + for (i=0;i 255 -#define MULTI_PROTO_D1X_MINOR 1 //Incrementing this seems the only way possible. Still stays backwards compitible. // PROTOCOL VARIABLES AND DEFINES - END @@ -114,10 +111,9 @@ extern int multi_protocol; // set and determinate used protocol #define MULTI_REQ_PLAYER 35 // NEVER USED #define MULTI_SEND_PLAYER 36 // NEVER USED -#define MULTI_PLAYER_POWERUP_COUNT 37 -#define MULTI_START_POWERUP_COUNT 38 +#define MULTI_POWCAP_UPDATE 37 -#define MULTI_MAX_TYPE 38 +#define MULTI_MAX_TYPE 37 #define MAX_MULTI_MESSAGE_LEN 90 //didn't change it, just moved it up @@ -209,8 +205,6 @@ void multi_send_audio_taunt(int taunt_num); void multi_send_score(void); void multi_send_trigger(int trigger); void multi_send_hostage_door_status(int wallnum); -void multi_send_player_powerup_count(); -void multi_send_start_powerup_count(); void multi_endlevel_score(void); void multi_consistency_error(int reset); @@ -254,6 +248,9 @@ extern int Network_send_object_mode; extern int Network_send_objnum; extern int Network_rejoined; extern int Network_new_game; +extern int Network_sending_extras; +extern int VerifyPlayerJoined; +extern int Player_joining_extras; extern int Network_player_added; extern int message_length[MULTI_MAX_TYPE+1]; @@ -295,6 +292,7 @@ extern int multi_sending_message; extern int multi_defining_message; extern int multi_message_input_sub(int key); extern void multi_send_message_start(); +extern int multi_powerup_is_4pack(int); extern void multi_message_feedback(); extern int control_invul_time; @@ -316,13 +314,17 @@ int multi_i_am_master(void); int multi_who_is_master(void); void change_playernum_to(int new_pnum); +// Multiplayer powerup capping +extern void multi_powcap_count_powerups_in_mine(void); +extern void multi_powcap_cap_objects(); +extern void multi_do_powcap_update(); +extern void multi_send_powcap_update(); + // Globals for protocol-bound Refuse-functions extern char RefuseThisPlayer,WaitForRefuseAnswer,RefuseTeam,RefusePlayerName[12]; extern fix64 RefuseTimeLimit; #define REFUSE_INTERVAL (F1_0*8) -extern uint multi_allow_powerup; - extern struct netgame_info Netgame; /* diff --git a/main/multibot.c b/main/multibot.c index 8722a795c..9092a2af5 100644 --- a/main/multibot.c +++ b/main/multibot.c @@ -1044,8 +1044,6 @@ multi_do_create_robot_powerups(char *buf) if (egg_objnum == -1) return; // Object buffer full - pow_add_random(&del_obj); - // Assert(egg_objnum > -1); Assert((Net_create_loc > 0) && (Net_create_loc <= MAX_ROBOT_POWERUPS)); @@ -1125,7 +1123,6 @@ multi_drop_robot_powerups(int objnum) if (egg_objnum >= 0) { // Transmit the object creation to the other players multi_send_create_robot_powerups(del_obj); - pow_add_random(del_obj); } } diff --git a/main/net_ipx.c b/main/net_ipx.c index c2cdaae7d..f7c5e6398 100644 --- a/main/net_ipx.c +++ b/main/net_ipx.c @@ -92,6 +92,8 @@ IPX_sequence_packet IPX_Seq; extern obj_position Player_init[MAX_PLAYERS]; extern void game_disable_cheats(); int net_ipx_wait_for_snyc(); +extern char MaxPowerupsAllowed[MAX_POWERUP_TYPES]; +extern char PowerupsInMine[MAX_POWERUP_TYPES]; /* General IPX functions - START */ ubyte broadcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -426,7 +428,7 @@ void net_ipx_send_sequence_packet(IPX_sequence_packet seq, ubyte *server, ubyte tmps = INTEL_SHORT(seq.player.protocol.ipx.socket); memcpy(&(out_buffer[loc]), &tmps, 2); loc += 2; out_buffer[loc] = seq.player.connected; loc++; - out_buffer[loc] = MULTI_PROTO_D1X_MINOR; loc++; + out_buffer[loc] = 1; loc++; // 1 was MULTI_PROTO_D1X_MINOR if (net_address != NULL) ipxdrv_send_packet_data( out_buffer, loc, server, node, net_address); @@ -563,7 +565,13 @@ net_ipx_init(void) // So you want to play a netgame, eh? Let's a get a few things // straight - int save_pnum = Player_num; + int save_pnum = Player_num, t; + + for (t=0;tplayer.callsign)) ) { Network_send_objects = 0; + Network_sending_extras=0; Network_rejoined=0; + Player_joining_extras=-1; Network_send_objnum = -1; } } @@ -1431,6 +1446,9 @@ void net_udp_send_objects(void) Network_send_objects = 0; obj_count = 0; + Network_sending_extras=10; // start to send extras + VerifyPlayerJoined = Player_joining_extras = player_num; + return; } // mode == 1; } // i > Highest_object_index @@ -1557,7 +1575,9 @@ void net_udp_send_rejoin_sync(int player_num) // have to stop and try again after the level. net_udp_dump_player(UDP_sync_player.player.protocol.udp.addr, DUMP_ENDLEVEL); + Network_send_objects = 0; + Network_sending_extras=0; return; } @@ -1597,6 +1617,31 @@ void net_udp_send_rejoin_sync(int player_num) return; } +void net_udp_resend_sync_due_to_packet_loss() +{ + int i,j; + + if (!multi_i_am_master()) + return; + + net_udp_update_netgame(); + + // Fill in the kill list + for (j=0; j1 && Player_joining_extras!=-1) + net_udp_send_extras(); + Netgame.numplayers = 0; nsave=N_players; N_players=0; @@ -3688,8 +3734,12 @@ void net_udp_do_frame(int force, int listen) { net_udp_timeout_check(time); net_udp_listen(); + if (VerifyPlayerJoined!=-1 && !(FrameCount & 63)) + net_udp_resend_sync_due_to_packet_loss(); // This will resend to UDP_sync_player if (Network_send_objects) net_udp_send_objects(); + if (Network_sending_extras && VerifyPlayerJoined==-1) + net_udp_send_extras(); } PacketUrgent = 0; @@ -4182,6 +4232,12 @@ void net_udp_read_pdata_short_packet(UDP_frame_info *pd) TheirPlayernum = pd->Player_num; TheirObjnum = Players[pd->Player_num].objnum; + if (VerifyPlayerJoined!=-1 && TheirPlayernum==VerifyPlayerJoined) + { + // Hurray! Someone really really got in the game (I think). + VerifyPlayerJoined=-1; + } + if (!multi_quit_game && (TheirPlayernum >= N_players)) { if (Network_status!=NETSTAT_WAITING) @@ -4432,6 +4488,18 @@ int net_udp_get_new_player_num (UDP_sequence_packet *their) } } +void net_udp_send_extras () +{ + Assert (Player_joining_extras>-1); + + if (Network_sending_extras==10) + multi_send_powcap_update(); + + Network_sending_extras--; + if (!Network_sending_extras) + Player_joining_extras=-1; +} + static int show_game_rules_handler(window *wind, d_event *event, netgame_info *netgame) { int k; diff --git a/main/object.c b/main/object.c index 47cf79d93..909d2f5fb 100644 --- a/main/object.c +++ b/main/object.c @@ -1298,7 +1298,7 @@ void set_camera_pos(vms_vector *camera_pos, object *objp) } } -extern void drop_player_eggs(object *objp); +extern void drop_player_eggs(object *playerobj); extern int get_explosion_vclip(object *obj,int stage); // ------------------------------------------------------------------------------------------------------------------ @@ -1365,14 +1365,18 @@ void dead_player_frame(void) HUD_init_message(HM_DEFAULT, TXT_SHIP_DESTROYED_0); Player_exploded = 1; - drop_player_eggs(ConsoleObject); - Player_eggs_dropped = 1; - #ifdef NETWORK - if (Game_mode & GM_MULTI) - { - multi_send_player_explode(MULTI_PLAYER_EXPLODE); - } - #endif +#ifdef NETWORK + if (Game_mode & GM_NETWORK) + multi_powcap_cap_objects(); +#endif + drop_player_eggs(ConsoleObject); + Player_eggs_dropped = 1; +#ifdef NETWORK + if (Game_mode & GM_MULTI) + { + multi_send_player_explode(MULTI_PLAYER_EXPLODE); + } +#endif explode_badass_player(ConsoleObject); @@ -1393,21 +1397,25 @@ void dead_player_frame(void) } - if (Death_sequence_aborted) - { - if (!Player_eggs_dropped) - { - drop_player_eggs(ConsoleObject); - Player_eggs_dropped = 1; - #ifdef NETWORK - if (Game_mode & GM_MULTI) - { - multi_send_player_explode(MULTI_PLAYER_EXPLODE); - } - #endif - } - DoPlayerDead(); //kill_player(); - } + if (Death_sequence_aborted) + { + if (!Player_eggs_dropped) + { +#ifdef NETWORK + if (Game_mode & GM_NETWORK) + multi_powcap_cap_objects(); +#endif + drop_player_eggs(ConsoleObject); + Player_eggs_dropped = 1; +#ifdef NETWORK + if (Game_mode & GM_MULTI) + { + multi_send_player_explode(MULTI_PLAYER_EXPLODE); + } +#endif + } + DoPlayerDead(); //kill_player(); + } } else time_dead = 0; diff --git a/main/powerup.c b/main/powerup.c index 61322dea4..383d40ea1 100644 --- a/main/powerup.c +++ b/main/powerup.c @@ -449,199 +449,6 @@ int do_powerup(object *obj) } -void pow_count_add(int *pow_level, int id, int count, object *pow) { - switch (id) { - case POW_VULCAN_WEAPON: - if (pow != NULL) - pow_level[POW_VULCAN_AMMO] += pow->ctype.powerup_info.count; - else - pow_level[POW_VULCAN_AMMO] += VULCAN_WEAPON_AMMO_AMOUNT * count; - pow_level[POW_VULCAN_WEAPON] += count; - break; - case POW_VULCAN_AMMO: - pow_level[POW_VULCAN_AMMO] += VULCAN_AMMO_AMOUNT * count; - break; - case POW_MISSILE_4: - case POW_HOMING_AMMO_4: - pow_level[id - 1] += 4 * count; - break; - default: - pow_level[id] += count; - } -} - -void pow_count_level(int *pow_level) { - int i; - - memset(pow_level, 0, MAX_POWERUP_TYPES * sizeof(pow_level[0])); - for (i = 0; i <= Highest_object_index; i++) - if (!(Objects[i].flags & OF_SHOULD_BE_DEAD)) - switch (Objects[i].type) { - case OBJ_POWERUP: - pow_count_add(pow_level, Objects[i].id, 1, &Objects[i]); - break; -#if 0 // now not added until released by robot - case OBJ_ROBOT: - if (Objects[i].contains_type == OBJ_POWERUP) - pow_count_add(pow_level, Objects[i].contains_id, Objects[i].contains_count, NULL); - break; -#endif - } -} - -void count_powerup_start_level() { - int player_pows[MAX_POWERUP_TYPES]; - - pow_count_level(powerup_start_level); - player_to_pow_count(&Players[Player_num], player_pows); - pow_add_level_pow_count(player_pows); -} - -#ifndef NDEBUG -void dump_pow_count(char *title, int *pow_count); -#endif - -// add a random created powerup to the level count -void pow_add_random(object *obj) { - if (obj->contains_count > 0 && obj->contains_type == OBJ_POWERUP) - pow_count_add(powerup_start_level, obj->contains_id, obj->contains_count, NULL); - #ifndef NDEBUG -#ifdef USE_IPX - if (!(Game_mode & GM_NETWORK) || - Netgame.protocol.ipx.protocol_version != MULTI_PROTO_D1X_VER) - return; -#endif - dump_pow_count("pow_add_random: now start level", powerup_start_level); - #endif -} - -void pow_add_level_pow_count(int *pow_count) { - int i; - - for (i = 0; i < MAX_POWERUP_TYPES; i++) - powerup_start_level[i] += pow_count[i]; - #ifndef NDEBUG -#ifdef USE_IPX - if (!(Game_mode & GM_NETWORK) || - Netgame.protocol.ipx.protocol_version != MULTI_PROTO_D1X_VER) - return; -#endif - dump_pow_count("pow_add_level_pow_count: pow_count", pow_count); - dump_pow_count("pow_add_level_pow_count: now start level", powerup_start_level); - #endif -} - -#if 0 // clipping version -// fill pow_count with items that would be dropped if player dies -void player_to_pow_count(player *player, int *pow_count) -{ - memset(pow_count, 0, sizeof(int) * MAX_POWERUP_TYPES); - pow_count[POW_LASER] = player->laser_level; - pow_count[POW_QUAD_FIRE] = (player->flags & PLAYER_FLAGS_QUAD_LASERS) != 0; - pow_count[POW_CLOAK] = (player->flags & PLAYER_FLAGS_CLOAKED) != 0; - pow_count[POW_VULCAN_WEAPON] = (player->primary_weapon_flags & HAS_VULCAN_FLAG) != 0; - pow_count[POW_SPREADFIRE_WEAPON] = (player->primary_weapon_flags & HAS_SPREADFIRE_FLAG) != 0; - pow_count[POW_PLASMA_WEAPON] = (player->primary_weapon_flags & HAS_PLASMA_FLAG) != 0; - pow_count[POW_FUSION_WEAPON] = (player->primary_weapon_flags & HAS_FUSION_FLAG) != 0; - pow_count[POW_MISSILE_1] = MIN(player->secondary_ammo[CONCUSSION_INDEX], 4); - pow_count[POW_HOMING_AMMO_1] = MIN(player->secondary_ammo[HOMING_INDEX], 6); - pow_count[POW_PROXIMITY_WEAPON] = MIN((player->secondary_ammo[PROXIMITY_INDEX]+2)/4, 3); - pow_count[POW_SMARTBOMB_WEAPON] = MIN(player->secondary_ammo[SMART_INDEX], 3); - pow_count[POW_MEGA_WEAPON] = MIN(player->secondary_ammo[MEGA_INDEX], 3); - pow_count[POW_VULCAN_AMMO] = MIN(player->primary_ammo[VULCAN_INDEX], 200); - pow_count[POW_INVULNERABILITY] = (player->flags & PLAYER_FLAGS_INVULNERABLE) != 0; - // Always drop a shield and energy powerup in multiplayer - if (Game_mode & GM_MULTI) { - pow_count[POW_SHIELD_BOOST] = 1; - pow_count[POW_ENERGY] = 1; - } -} -#else -// fill pow_count with items that player currently has -void player_to_pow_count(player *player, int *pow_count) -{ - memset(pow_count, 0, sizeof(int) * MAX_POWERUP_TYPES); - pow_count[POW_LASER] = player->laser_level; - pow_count[POW_QUAD_FIRE] = (player->flags & PLAYER_FLAGS_QUAD_LASERS) != 0; - pow_count[POW_CLOAK] = (player->flags & PLAYER_FLAGS_CLOAKED) != 0; - pow_count[POW_VULCAN_WEAPON] = (player->primary_weapon_flags & HAS_VULCAN_FLAG) != 0; - pow_count[POW_SPREADFIRE_WEAPON] = (player->primary_weapon_flags & HAS_SPREADFIRE_FLAG) != 0; - pow_count[POW_PLASMA_WEAPON] = (player->primary_weapon_flags & HAS_PLASMA_FLAG) != 0; - pow_count[POW_FUSION_WEAPON] = (player->primary_weapon_flags & HAS_FUSION_FLAG) != 0; - pow_count[POW_MISSILE_1] = player->secondary_ammo[CONCUSSION_INDEX]; - pow_count[POW_HOMING_AMMO_1] = player->secondary_ammo[HOMING_INDEX]; - pow_count[POW_PROXIMITY_WEAPON] = (player->secondary_ammo[PROXIMITY_INDEX]+2)/4; - pow_count[POW_SMARTBOMB_WEAPON] = player->secondary_ammo[SMART_INDEX]; - pow_count[POW_MEGA_WEAPON] = player->secondary_ammo[MEGA_INDEX]; - pow_count[POW_VULCAN_AMMO] = player->primary_ammo[VULCAN_INDEX]; - pow_count[POW_INVULNERABILITY] = (player->flags & PLAYER_FLAGS_INVULNERABLE) != 0; - // Always drop a shield and energy powerup in multiplayer - if (Game_mode & GM_MULTI) { - pow_count[POW_SHIELD_BOOST] = 1; - pow_count[POW_ENERGY] = 1; - } -} -#endif - - -// This must be in a special order to keep the -// Net_create_objnums[] order compatible -int player_drop_powerups[] = { POW_LASER, POW_QUAD_FIRE, POW_CLOAK, - POW_VULCAN_WEAPON, POW_SPREADFIRE_WEAPON, POW_PLASMA_WEAPON, - POW_FUSION_WEAPON, POW_PROXIMITY_WEAPON, POW_SMARTBOMB_WEAPON, - POW_MEGA_WEAPON, POW_HOMING_AMMO_1, POW_VULCAN_AMMO, - POW_MISSILE_1, POW_SHIELD_BOOST, POW_ENERGY, - POW_INVULNERABILITY }; - -// reduce player drop powerups -void clip_player_pow_count(int *pow_count) -{ - int i; - /*laser,quad,cloak,vulc,spread,plasma,fusion,*/ - /*prox,smart,mega,hom,vula,con,sh,en,invul*/ - static int pow_max[NUM_PLAYER_DROP_POWERUPS] = - { 3,1,1,1,1,1,1,3,3,3,6,VULCAN_AMMO_MAX,4,1,1,0 }; - for (i = 0; i < NUM_PLAYER_DROP_POWERUPS; i++) - if (pow_count[player_drop_powerups[i]] > pow_max[i]) - pow_count[player_drop_powerups[i]] = pow_max[i]; -} - -// may this powerup be added to the level? -// returns number of powerups left if true, -1 if unknown, otherwise 0. -int may_create_powerup(int powerup) -{ -#ifdef NETWORK - int pow_count[MAX_POWERUP_TYPES]; - - if (!(Game_mode & GM_NETWORK) -#ifdef USE_IPX - || Netgame.protocol.ipx.protocol_version != MULTI_PROTO_D1X_VER -#endif - ) - return -1; // say unknown if not in D1X network game - pow_count_level(pow_count); -#ifndef NDEBUG - dump_pow_count("may_create_powerup: now in level:", pow_count); -#endif -// if(powerup==POW_SHIELD_BOOST) return 1; - return max(powerup_start_level[powerup] - pow_count[powerup], 0); -#endif - return -1; -} - - -#ifndef NDEBUG -void dump_pow_count(char *title, int *pow_count) { - int i, j = 0; - - for (i = 0; i < MAX_POWERUP_TYPES; i++) { - if (pow_count[i]) { - j++; - } - } -} -#endif - /* * reads n powerup_type_info structs from a CFILE */ diff --git a/main/powerup.h b/main/powerup.h index 3a3ce61f7..040414ff0 100644 --- a/main/powerup.h +++ b/main/powerup.h @@ -117,26 +117,6 @@ extern void do_megawow_powerup(int quantity); extern void powerup_basic(int redadd, int greenadd, int blueadd, int score, char *format, ...); -extern void count_powerup_start_level(); - -extern int powerup_start_level[MAX_POWERUP_TYPES]; - -extern void pow_count_level(); - -extern void pow_add_random(); - -// add pow_count to powerup_start_level -extern void pow_add_level_pow_count(int *pow_count); - -// fill pow_count with items that would be dropped if player dies -extern void player_to_pow_count(player *player, int *pow_count); - -#define NUM_PLAYER_DROP_POWERUPS 16 -extern int player_drop_powerups[NUM_PLAYER_DROP_POWERUPS]; - -// reduce player drop powerups -extern void clip_player_pow_count(int *pow_count); - // may this powerup be added to the level? // returns number of powerups left if true, otherwise 0. extern int may_create_powerup(int powerup); diff --git a/main/weapon.c b/main/weapon.c index 075a6e68b..b53629cad 100644 --- a/main/weapon.c +++ b/main/weapon.c @@ -33,6 +33,10 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. // Convert primary weapons to indices in Weapon_info array. ubyte Primary_weapon_to_weapon_info[MAX_PRIMARY_WEAPONS] = {0, 11, 12, 13, 14}; ubyte Secondary_weapon_to_weapon_info[MAX_SECONDARY_WEAPONS] = {8, 15, 16, 17, 18}; +//for each primary weapon, what kind of powerup gives weapon +ubyte Primary_weapon_to_powerup[MAX_PRIMARY_WEAPONS] = {POW_LASER,POW_VULCAN_WEAPON,POW_SPREADFIRE_WEAPON,POW_PLASMA_WEAPON,POW_FUSION_WEAPON}; +//for each Secondary weapon, what kind of powerup gives weapon +ubyte Secondary_weapon_to_powerup[MAX_SECONDARY_WEAPONS] = {POW_MISSILE_1,POW_HOMING_AMMO_1,POW_PROXIMITY_WEAPON,POW_SMARTBOMB_WEAPON,POW_MEGA_WEAPON}; int Primary_ammo_max[MAX_PRIMARY_WEAPONS] = {0, VULCAN_AMMO_MAX, 0, 0, 0}; ubyte Secondary_ammo_max[MAX_SECONDARY_WEAPONS] = {20, 10, 10, 5, 5}; weapon_info Weapon_info[MAX_WEAPON_TYPES]; diff --git a/main/weapon.h b/main/weapon.h index fe012908f..631f5e459 100644 --- a/main/weapon.h +++ b/main/weapon.h @@ -90,6 +90,9 @@ typedef struct weapon_info { #define MAX_PRIMARY_WEAPONS 5 #define MAX_SECONDARY_WEAPONS 5 +//given a weapon index, return the flag value +#define HAS_FLAG(index) (1<<(index)) + // Weapon flags, if player->weapon_flags & WEAPON_FLAG is set, then the player has this weapon #define HAS_LASER_FLAG 0x001 #define HAS_VULCAN_FLAG 0x002 @@ -130,6 +133,10 @@ extern sbyte Primary_weapon, Secondary_weapon; extern ubyte Primary_weapon_to_weapon_info[MAX_PRIMARY_WEAPONS]; extern ubyte Secondary_weapon_to_weapon_info[MAX_SECONDARY_WEAPONS]; +//for each primary weapon, what kind of powerup gives weapon +extern ubyte Primary_weapon_to_powerup[MAX_SECONDARY_WEAPONS]; +//for each Secondary weapon, what kind of powerup gives weapon +extern ubyte Secondary_weapon_to_powerup[MAX_SECONDARY_WEAPONS]; extern void auto_select_weapon(int weapon_type); //parm is primary or secondary extern void select_weapon(int weapon_num, int secondary_flag, int print_message,int wait_for_rearm);