X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Ft_items.qc;h=feefd10985aa37763770520146704e307b78ae87;hp=6a6ce3fafdccd004a36a7c438b820b8423414040;hb=13e8382b4bd9c0de8bcfd2a96f56e638ba5d431d;hpb=b2d3d16a9a3e5df1c518ecd2fce0bfa741db190a diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index 6a6ce3fafd..feefd10985 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -533,7 +533,7 @@ void Item_Respawn (entity this) void Item_RespawnCountdown (entity this) { - if(this.count >= ITEM_RESPAWN_TICKS) + if(this.item_respawncounter >= ITEM_RESPAWN_TICKS) { if(this.waypointsprite_attached) WaypointSprite_Kill(this.waypointsprite_attached); @@ -542,8 +542,8 @@ void Item_RespawnCountdown (entity this) else { this.nextthink = time + 1; - this.count += 1; - if(this.count == 1) + this.item_respawncounter += 1; + if(this.item_respawncounter == 1) { do { { @@ -584,7 +584,7 @@ void Item_RespawnCountdown (entity this) }); WaypointSprite_Ping(this.waypointsprite_attached); - //WaypointSprite_UpdateHealth(this.waypointsprite_attached, this.count); + //WaypointSprite_UpdateHealth(this.waypointsprite_attached, this.item_respawncounter); } } } @@ -607,7 +607,7 @@ void Item_ScheduleRespawnIn(entity e, float t) setthink(e, Item_RespawnCountdown); e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS); e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS; - e.count = 0; + e.item_respawncounter = 0; if(Item_ItemsTime_Allow(e.itemdef) || (e.weapons & WEPSET_SUPERWEAPONS)) { t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime); @@ -682,146 +682,74 @@ void Item_ScheduleInitialRespawn(entity e) Item_ScheduleRespawnIn(e, max(0, game_starttime - time) + ((e.respawntimestart) ? e.respawntimestart : ITEM_RESPAWNTIME_INITIAL(e))); } -void GivePlayerResource(entity player, .float resource_type, float amount) +void GiveRandomWeapons(entity receiver, int num_weapons, string weapon_names, + entity ammo_entity) { - if (amount == 0) + if (num_weapons == 0) { return; } - switch (resource_type) + int num_potential_weapons = tokenize_console(weapon_names); + for (int give_attempt = 0; give_attempt < num_weapons; ++give_attempt) { - case health: + RandomSelection_Init(); + for (int weapon_index = 0; weapon_index < num_potential_weapons; + ++weapon_index) { - // Ugly hack. We do not check if health goes beyond hard limit since - // currently it is done in player_regen. We need to bring back this - // check when other code is ported to this function. - player.health = bound(player.health, player.health + amount, - autocvar_g_balance_health_limit); - // Correct code: - //player.health = bound(player.health, player.health + amount, - // min(autocvar_g_balance_health_limit, - // RESOURCE_AMOUNT_HARD_LIMIT)); - player.pauserothealth_finished = max(player.pauserothealth_finished, - time + autocvar_g_balance_pause_health_rot); - return; + string weapon = argv(weapon_index); + FOREACH(Weapons, it != WEP_Null, + { + // Finding a weapon which player doesn't have. + if (!(receiver.weapons & it.m_wepset) && (it.netname == weapon)) + { + RandomSelection_AddEnt(it, 1, 1); + break; + } + }); } - case armorvalue: + if (RandomSelection_chosen_ent == NULL) { - // Ugly hack. We do not check if armor goes beyond hard limit since - // currently it is done in player_regen. We need to bring back this - // check when other code is ported to this function. - player.armorvalue = bound(player.armorvalue, player.armorvalue + - amount, autocvar_g_balance_armor_limit); - // Correct code: - //player.armorvalue = bound(player.armorvalue, player.armorvalue + - // amount, min(autocvar_g_balance_armor_limit, - // RESOURCE_AMOUNT_HARD_LIMIT)); - player.pauserotarmor_finished = max(player.pauserotarmor_finished, - time + autocvar_g_balance_pause_armor_rot); return; } - case ammo_shells: - case ammo_nails: - case ammo_rockets: - case ammo_cells: - case ammo_plasma: + receiver.weapons |= RandomSelection_chosen_ent.m_wepset; + if (RandomSelection_chosen_ent.ammo_type == RESOURCE_NONE) { - GivePlayerAmmo(player, resource_type, amount); - return; + continue; } - case ammo_fuel: + if (GetResourceAmount(receiver, + RandomSelection_chosen_ent.ammo_type) != 0) { - player.ammo_fuel = bound(player.ammo_fuel, player.ammo_fuel + - amount, min(g_pickup_fuel_max, RESOURCE_AMOUNT_HARD_LIMIT)); - player.pauserotfuel_finished = max(player.pauserotfuel_finished, - time + autocvar_g_balance_pause_fuel_rot); - return; + continue; } + GiveResource(receiver, RandomSelection_chosen_ent.ammo_type, + GetResourceAmount(ammo_entity, + RandomSelection_chosen_ent.ammo_type)); } } -void GivePlayerHealth(entity player, float amount) -{ - GivePlayerResource(player, health, amount); -} - -void GivePlayerArmor(entity player, float amount) -{ - GivePlayerResource(player, armorvalue, amount); -} - -void GivePlayerAmmo(entity player, .float ammotype, float amount) +float Item_GiveAmmoTo(entity item, entity player, int resource_type, float ammomax) { + float amount = GetResourceAmount(item, resource_type); if (amount == 0) { - return; - } - float maxvalue = RESOURCE_AMOUNT_HARD_LIMIT; - switch (ammotype) - { - case ammo_shells: - { - maxvalue = g_pickup_shells_max; - break; - } - case ammo_cells: - { - maxvalue = g_pickup_cells_max; - break; - } - case ammo_rockets: - { - maxvalue = g_pickup_rockets_max; - break; - } - case ammo_plasma: - { - maxvalue = g_pickup_plasma_max; - break; - } - case ammo_nails: - { - maxvalue = g_pickup_nails_max; - break; - } - } - player.(ammotype) = min(player.(ammotype) + amount, - min(maxvalue, RESOURCE_AMOUNT_HARD_LIMIT)); -} - -void GivePlayerFuel(entity player, float amount) -{ - GivePlayerResource(player, ammo_fuel, amount); -} - -float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax) -{ - if (!item.(ammotype)) return false; - + } + float player_amount = GetResourceAmount(player, resource_type); if (item.spawnshieldtime) { - if ((player.(ammotype) < ammomax) || item.pickup_anyway > 0) + if ((player_amount >= ammomax) && (item.pickup_anyway <= 0)) { - float amount = item.(ammotype); - if ((player.(ammotype) + amount) > ammomax) - { - amount = ammomax - player.(ammotype); - } - GivePlayerResource(player, ammotype, amount); - return true; + return false; } + GiveResourceWithLimit(player, resource_type, amount, ammomax); + return true; } - else if(g_weapon_stay == 2) + if (g_weapon_stay != 2) { - float mi = min(item.(ammotype), ammomax); - if (player.(ammotype) < mi) - { - GivePlayerResource(player, ammotype, mi - player.(ammotype)); - } - return true; + return false; } - return false; + GiveResourceWithLimit(player, resource_type, amount, min(amount, ammomax)); + return true; } float Item_GiveTo(entity item, entity player) @@ -850,14 +778,14 @@ float Item_GiveTo(entity item, entity player) } } } - pickedup |= Item_GiveAmmoTo(item, player, health, item.max_health); - pickedup |= Item_GiveAmmoTo(item, player, armorvalue, item.max_armorvalue); - pickedup |= Item_GiveAmmoTo(item, player, ammo_shells, g_pickup_shells_max); - pickedup |= Item_GiveAmmoTo(item, player, ammo_nails, g_pickup_nails_max); - pickedup |= Item_GiveAmmoTo(item, player, ammo_rockets, g_pickup_rockets_max); - pickedup |= Item_GiveAmmoTo(item, player, ammo_cells, g_pickup_cells_max); - pickedup |= Item_GiveAmmoTo(item, player, ammo_plasma, g_pickup_plasma_max); - pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_HEALTH, item.max_health); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_ARMOR, item.max_armorvalue); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_SHELLS, g_pickup_shells_max); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_BULLETS, g_pickup_nails_max); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_ROCKETS, g_pickup_rockets_max); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_CELLS, g_pickup_cells_max); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_PLASMA, g_pickup_plasma_max); + pickedup |= Item_GiveAmmoTo(item, player, RESOURCE_FUEL, g_pickup_fuel_max); if (item.itemdef.instanceOfWeaponPickup) { WepSet w; @@ -914,8 +842,6 @@ float Item_GiveTo(entity item, entity player) player.superweapons_finished = max(player.superweapons_finished, time) + item.superweapons_finished; } -LABEL(skip) - // always eat teamed entities if(item.team) pickedup = true; @@ -951,9 +877,8 @@ LABEL(skip) void Item_Touch(entity this, entity toucher) { - // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky) - if (this.classname == "droppedweapon") + if (Item_IsLoot(this)) { if (ITEM_TOUCH_NEEDKILL()) { @@ -978,17 +903,16 @@ void Item_Touch(entity this, entity toucher) toucher = M_ARGV(1, entity); - if (this.classname == "droppedweapon") + if (Item_IsExpiring(this)) { this.strength_finished = max(0, this.strength_finished - time); this.invincible_finished = max(0, this.invincible_finished - time); this.superweapons_finished = max(0, this.superweapons_finished - time); } - entity it = this.itemdef; - bool gave = ITEM_HANDLE(Pickup, it, this, toucher); + bool gave = ITEM_HANDLE(Pickup, this.itemdef, this, toucher); if (!gave) { - if (this.classname == "droppedweapon") + if (Item_IsExpiring(this)) { // undo what we did above this.strength_finished += time; @@ -1005,29 +929,40 @@ LABEL(pickup) Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1); _sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM); - if (this.classname == "droppedweapon") + MUTATOR_CALLHOOK(ItemTouched, this, toucher); + if (wasfreed(this)) + { + return; + } + + if (Item_IsLoot(this)) + { delete(this); - else if (this.spawnshieldtime) + return; + } + if (!this.spawnshieldtime) + { + return; + } + entity e; + if (this.team) { - entity e; - if(this.team) + RandomSelection_Init(); + IL_EACH(g_items, it.team == this.team, { - RandomSelection_Init(); - IL_EACH(g_items, it.team == this.team, + if (it.itemdef) // is a registered item { - if(it.itemdef) // is a registered item - { - Item_Show(it, -1); - RandomSelection_AddEnt(it, it.cnt, 0); - } - }); - e = RandomSelection_chosen_ent; - Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway) - } - else - e = this; - Item_ScheduleRespawn(e); + Item_Show(it, -1); + it.scheduledrespawntime = 0; + RandomSelection_AddEnt(it, it.cnt, 0); + } + }); + e = RandomSelection_chosen_ent; + Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway) } + else + e = this; + Item_ScheduleRespawn(e); } void Item_Reset(entity this) @@ -1035,16 +970,19 @@ void Item_Reset(entity this) Item_Show(this, !this.state); setorigin(this, this.origin); - if (this.classname != "droppedweapon") + if (Item_IsLoot(this)) { - setthink(this, Item_Think); - this.nextthink = time; - - if (this.waypointsprite_attached) - WaypointSprite_Kill(this.waypointsprite_attached); - - if (this.itemdef.instanceOfPowerup || (this.weapons & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially! - Item_ScheduleInitialRespawn(this); + return; + } + setthink(this, Item_Think); + this.nextthink = time; + if (this.waypointsprite_attached) + { + WaypointSprite_Kill(this.waypointsprite_attached); + } + if (this.itemdef.instanceOfPowerup || (this.weapons & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially! + { + Item_ScheduleInitialRespawn(this); } } @@ -1149,14 +1087,14 @@ float ammo_pickupevalfunc(entity player, entity item) if(!(player.weapons & (it.m_wepset))) continue; - switch(it.ammo_field) + switch(it.ammo_type) { - case ammo_shells: need_shells = true; break; - case ammo_nails: need_nails = true; break; - case ammo_rockets: need_rockets = true; break; - case ammo_cells: need_cells = true; break; - case ammo_plasma: need_plasma = true; break; - case ammo_fuel: need_fuel = true; break; + case RESOURCE_SHELLS: need_shells = true; break; + case RESOURCE_BULLETS: need_nails = true; break; + case RESOURCE_ROCKETS: need_rockets = true; break; + case RESOURCE_CELLS: need_cells = true; break; + case RESOURCE_PLASMA: need_plasma = true; break; + case RESOURCE_FUEL: need_fuel = true; break; } }); rating = item.bot_pickupbasevalue; @@ -1188,8 +1126,6 @@ float ammo_pickupevalfunc(entity player, entity item) return rating; } -.int item_group; -.int item_group_count; float healtharmor_pickupevalfunc(entity player, entity item) { float c = 0; @@ -1276,11 +1212,9 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default return; } - // is it a dropped weapon? - if (this.classname == "droppedweapon") + if (Item_IsLoot(this)) { this.reset = SUB_Remove; - // it's a dropped weapon set_movetype(this, MOVETYPE_TOSS); // Savage: remove thrown items after a certain period of time ("garbage collection") @@ -1290,7 +1224,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default this.takedamage = DAMAGE_YES; this.event_damage = Item_Damage; - if(this.strength_finished || this.invincible_finished || this.superweapons_finished) + if (Item_IsExpiring(this)) { // if item is worthless after a timer, have it expire then this.nextthink = max(this.strength_finished, this.invincible_finished, this.superweapons_finished); @@ -1405,7 +1339,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if(def.instanceOfWeaponPickup) { - if (this.classname != "droppedweapon") // if dropped, colormap is already set up nicely + if (!Item_IsLoot(this)) // if dropped, colormap is already set up nicely this.colormap = 1024; // color shirt=0 pants=0 grey else this.gravity = 1; @@ -1441,6 +1375,13 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default void StartItem(entity this, GameItem def) { + def = def.m_spawnfunc_hookreplace(def, this); + if (def.spawnflags & ITEM_FLAG_MUTATORBLOCKED) + { + delete(this); + return; + } + this.classname = def.m_canonical_spawnfunc; _StartItem( this, this.itemdef = def, @@ -1497,114 +1438,9 @@ void setItemGroupCount() } } -spawnfunc(item_rockets) -{ - StartItem(this, ITEM_Rockets); -} - -spawnfunc(item_bullets) -{ - if(!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap && - (this.classname != "droppedweapon")) - { - weaponswapping = true; - spawnfunc_item_shells(this); - weaponswapping = false; - return; - } - - StartItem(this, ITEM_Bullets); -} - -spawnfunc(item_cells) -{ - StartItem(this, ITEM_Cells); -} - -spawnfunc(item_plasma) -{ - StartItem(this, ITEM_Plasma); -} - -spawnfunc(item_shells) -{ - if(!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap && - (this.classname != "droppedweapon")) - { - weaponswapping = true; - spawnfunc_item_bullets(this); - weaponswapping = false; - return; - } - - StartItem(this, ITEM_Shells); -} - -spawnfunc(item_armor_small) -{ - StartItem(this, ITEM_ArmorSmall); -} - -spawnfunc(item_armor_medium) -{ - StartItem(this, ITEM_ArmorMedium); -} - -spawnfunc(item_armor_big) -{ - StartItem(this, ITEM_ArmorBig); -} - -spawnfunc(item_armor_mega) -{ - StartItem(this, ITEM_ArmorMega); -} - -spawnfunc(item_health_small) -{ - StartItem(this, ITEM_HealthSmall); -} - -spawnfunc(item_health_medium) -{ - StartItem(this, ITEM_HealthMedium); -} - -spawnfunc(item_health_big) -{ - StartItem(this, ITEM_HealthBig); -} - -spawnfunc(item_health_mega) -{ - StartItem(this, ITEM_HealthMega); -} - -// support old misnamed entities -spawnfunc(item_armor1) { spawnfunc_item_armor_small(this); } // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard -spawnfunc(item_armor25) { spawnfunc_item_armor_mega(this); } -spawnfunc(item_armor_large) { spawnfunc_item_armor_mega(this); } -spawnfunc(item_health1) { spawnfunc_item_health_small(this); } -spawnfunc(item_health25) { spawnfunc_item_health_medium(this); } -spawnfunc(item_health_large) { spawnfunc_item_health_big(this); } -spawnfunc(item_health100) { spawnfunc_item_health_mega(this); } - -spawnfunc(item_strength) -{ - StartItem(this, ITEM_Strength); -} - -spawnfunc(item_invincible) -{ - StartItem(this, ITEM_Shield); -} - -// compatibility: -spawnfunc(item_quad) { this.classname = "item_strength";spawnfunc_item_strength(this);} - void target_items_use(entity this, entity actor, entity trigger) { - if(actor.classname == "droppedweapon") + if(Item_IsLoot(actor)) { EXACTTRIGGER_TOUCH(this, trigger); delete(actor); @@ -1619,7 +1455,7 @@ void target_items_use(entity this, entity actor, entity trigger) EXACTTRIGGER_TOUCH(this, trigger); } - IL_EACH(g_items, it.enemy == actor && it.classname == "droppedweapon", + IL_EACH(g_items, it.enemy == actor && Item_IsLoot(it), { delete(it); }); @@ -1741,31 +1577,6 @@ spawnfunc(target_items) } } -spawnfunc(item_fuel) -{ - StartItem(this, ITEM_JetpackFuel); -} - -spawnfunc(item_fuel_regen) -{ - if(start_items & ITEM_JetpackRegen.m_itemid) - { - spawnfunc_item_fuel(this); - return; - } - StartItem(this, ITEM_JetpackRegen); -} - -spawnfunc(item_jetpack) -{ - if(start_items & ITEM_Jetpack.m_itemid) - { - spawnfunc_item_fuel(this); - return; - } - StartItem(this, ITEM_Jetpack); -} - float GiveWeapon(entity e, float wpn, float op, float val) { WepSet v0, v1;