bool CommandParser::ParseStreamInner(BitStreamReader& f) { CMD cmd = (CMD)f.Read<byte>(); switch(cmd) { case CMD_ADD_EFFECT: { int netid; Effect e; f >> netid; f.ReadCasted<char>(e.effect); f.ReadCasted<char>(e.source); f.ReadCasted<char>(e.source_id); f >> e.power; f >> e.time; Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_ADD_EFFECT: Missing unit %d.", netid); return false; } if(e.effect >= EffectId::Max) { Error("CommandParser CMD_ADD_EFFECT: Invalid effect %d.", e.effect); return false; } if(e.source >= EffectSource::Max) { Error("CommandParser CMD_ADD_EFFECT: Invalid effect source %d.", e.source); return false; } if(e.source == EffectSource::Perk) { if(e.source_id >= (int)Perk::Max) { Error("CommandParser CMD_ADD_EFFECT: Invalid source id %d for perk source.", e.source_id); return false; } } else if(e.source_id != -1) { Error("CommandParser CMD_ADD_EFFECT: Invalid source id %d for source %d.", e.source_id, e.source); return false; } if(e.time > 0 && e.source != EffectSource::Temporary) { Error("CommandParser CMD_ADD_EFFECT: Invalid time %g for source %d.", e.time, e.source); return false; } unit->AddEffect(e); } break; case CMD_REMOVE_EFFECT: { int netid; EffectId effect; EffectSource source; int source_id; f >> netid; f.ReadCasted<char>(effect); f.ReadCasted<char>(source); f.ReadCasted<char>(source_id); Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_REMOVE_EFFECT: Missing unit %d.", netid); return false; } if(effect >= EffectId::Max) { Error("CommandParser CMD_REMOVE_EFFECT: Invalid effect %d.", effect); return false; } if(source >= EffectSource::Max) { Error("CommandParser CMD_REMOVE_EFFECT: Invalid effect source %d.", source); return false; } if(source == EffectSource::Perk) { if(source_id >= (int)Perk::Max) { Error("CommandParser CMD_REMOVE_EFFECT: Invalid source id %d for perk source.", source_id); return false; } } else if(source_id != -1) { Error("CommandParser CMD_REMOVE_EFFECT: Invalid source id %d for source %d.", source_id, source); return false; } RemoveEffect(unit, effect, source, source_id); } break; case CMD_LIST_EFFECTS: { int netid; f >> netid; Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_LIST_EFFECTS: Missing unit %d.", netid); return false; } ListEffects(unit); } break; case CMD_ADD_PERK: { int netid, value; Perk perk; f >> netid; f.ReadCasted<char>(perk); f.ReadCasted<char>(value); Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_ADD_PERK: Missing unit %d.", netid); return false; } if(!unit->player) { Error("CommandParser CMD_ADD_PERK: Unit %d is not player.", netid); return false; } if(perk >= Perk::Max) { Error("CommandParser CMD_ADD_PERK: Invalid perk %d.", perk); return false; } PerkInfo& info = PerkInfo::perks[(int)perk]; if(info.value_type == PerkInfo::None) { if(value != -1) { Error("CommandParser CMD_ADD_PERK: Invalid value %d for perk '%s'.", value, info.id); return false; } } else if(info.value_type == PerkInfo::Attribute) { if(value <= (int)AttributeId::MAX) { Error("CommandParser CMD_ADD_PERK: Invalid value %d for perk '%s'.", value, info.id); return false; } } else if(info.value_type == PerkInfo::Skill) { if(value <= (int)SkillId::MAX) { Error("CommandParser CMD_ADD_PERK: Invalid value %d for perk '%s'.", value, info.id); return false; } } AddPerk(unit->player, perk, value); } break; case CMD_REMOVE_PERK: { int netid, value; Perk perk; f >> netid; f.ReadCasted<char>(perk); f.ReadCasted<char>(value); Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_REMOVE_PERK: Missing unit %d.", netid); return false; } if(!unit->player) { Error("CommandParser CMD_REMOVE_PERK: Unit %d is not player.", netid); return false; } if(perk >= Perk::Max) { Error("CommandParser CMD_REMOVE_PERK: Invalid perk %d.", perk); return false; } PerkInfo& info = PerkInfo::perks[(int)perk]; if(info.value_type == PerkInfo::None) { if(value != -1) { Error("CommandParser CMD_REMOVE_PERK: Invalid value %d for perk '%s'.", value, info.id); return false; } } else if(info.value_type == PerkInfo::Attribute) { if(value <= (int)AttributeId::MAX) { Error("CommandParser CMD_REMOVE_PERK: Invalid value %d for perk '%s'.", value, info.id); return false; } } else if(info.value_type == PerkInfo::Skill) { if(value <= (int)SkillId::MAX) { Error("CommandParser CMD_REMOVE_PERK: Invalid value %d for perk '%s'.", value, info.id); return false; } } RemovePerk(unit->player, perk, value); } break; case CMD_LIST_PERKS: { int netid; f >> netid; Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_LIST_PERKS: Missing unit %d.", netid); return false; } if(!unit->player) { Error("CommandParser CMD_LIST_PERKS: Unit %d is not player.", netid); return false; } ListPerks(unit->player); } break; case CMD_LIST_STATS: { int netid; f >> netid; Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_LIST_STAT: Missing unit %d.", netid); return false; } ListStats(unit); } break; case CMD_ADD_LEARNING_POINTS: { int netid, count; f >> netid; f >> count; Unit* unit = L.FindUnit(netid); if(!unit) { Error("CommandParser CMD_ADD_LEARNING_POINTS: Missing unit %d.", netid); return false; } if(!unit->player) { Error("CommandParser CMD_ADD_LEARNING_POINTS: Unit %d is not player.", netid); return false; } if(count < 1) { Error("CommandParser CMD_ADD_LEARNING_POINTS: Invalid count %d.", count); return false; } unit->player->AddLearningPoint(count); } break; default: Error("Unknown generic command %u.", cmd); return false; } return true; }